# はじめに

Reproは従来型の定量分析に加え、各種分析機能からユーザーをターゲティングして、プッシュ通知やメッセージを配信できる機能を提供するアプリとWebサイトの成長支援プラットフォームです。

管理画面

iOS

Android

Web

React Native

Unity

Cordova

Monaca

Cocos2d-x

Flutter

## Index

* [動作環境](https://docs.repro.io/ja/requirements.md)
  * [Web](https://docs.repro.io/ja/requirements.md#web)
  * [iOS](https://docs.repro.io/ja/requirements.md#ios)
  * [Android](https://docs.repro.io/ja/requirements.md#android)
  * [Unity](https://docs.repro.io/ja/requirements.md#unity)
  * [Cordova](https://docs.repro.io/ja/requirements.md#cordova)
  * [Monaca](https://docs.repro.io/ja/requirements.md#monaca)
  * [Cocos2d-x](https://docs.repro.io/ja/requirements.md#cocos2d-x)
  * [React Native](https://docs.repro.io/ja/requirements.md#react-native)
  * [Flutter](https://docs.repro.io/ja/requirements.md#flutter)
  * [管理画面サポートブラウザ](https://docs.repro.io/ja/requirements.md#id2)
* [管理画面ガイド](https://docs.repro.io/ja/dashboard/index.md)
  * [アナリティクス](https://docs.repro.io/ja/dashboard/analytics/index.md)
  * [マーケティング](https://docs.repro.io/ja/dashboard/campaign/index.md)
  * [データエクスポート](https://docs.repro.io/ja/dashboard/export/index.md)
  * [イベント](https://docs.repro.io/ja/dashboard/event/index.md)
  * [ユーザープロフィール](https://docs.repro.io/ja/dashboard/user-profile/index.md)
  * [設定](https://docs.repro.io/ja/dashboard/setting/index.md)
  * [アカウント](https://docs.repro.io/ja/dashboard/account/index.md)
  * [その他](https://docs.repro.io/ja/dashboard/misc/index.md)
* [開発ガイド](https://docs.repro.io/ja/dev/index.md)
  * [アカウント作成](https://docs.repro.io/ja/dev/repro-account.md)
  * [iOS/Android SDK](https://docs.repro.io/ja/dev/sdk/index.md)
  * [Web](https://docs.repro.io/ja/dev/web/index.md)
  * [オーディエンスAPI](https://docs.repro.io/ja/dev/audience-api/index.md)
  * [オーディエンスインポート(β)](https://docs.repro.io/ja/dev/audience-import/index.md)
  * [プッシュAPI](https://docs.repro.io/ja/dev/push-api/index.md)
  * [イベントバルクトラッキング (β)](https://docs.repro.io/ja/dev/event-bulk-tracking/index.md)
  * [ユーザープロフィールAPI](https://docs.repro.io/ja/dev/user-profile-api/index.md)
  * [ユーザープロフィールバルクインポート](https://docs.repro.io/ja/dev/user-profile-bulk-import-api/index.md)
  * [ニュースフィードAPI](https://docs.repro.io/ja/dev/newsfeed-api/index.md)
  * [削除ユーザー登録API](https://docs.repro.io/ja/dev/user-data-deletions-api/index.md)
  * [メール](https://docs.repro.io/ja/dev/mail/index.md)
* [リリースノート](https://docs.repro.io/ja/releases/index.md)
  * [SDK](https://docs.repro.io/ja/releases/sdk/index.md)
  * [Web](https://docs.repro.io/ja/releases/web/index.md)
  * [ドメイン移行に伴う作業](https://docs.repro.io/ja/releases/change-domain/index.md)
  * [FCMへの移行手順](https://docs.repro.io/ja/releases/migration-to-fcm/index.md)
* [FAQ](https://docs.repro.io/ja/faq/index.md)
  * [App](https://docs.repro.io/ja/faq/app/index.md)
  * [Web](https://docs.repro.io/ja/faq/web/index.md)
  * [共通](https://docs.repro.io/ja/faq/general/index.md)

---

## 動作環境

##### NOTE
すでにサポートが終了したOSなどを継続して使用されることで、セキュリティ上のリスクがあると判断した場合、事前の通告なく動作環境を変更する可能性があります。

### Web

動作対象

- Google Chrome 39以上
- OS X/macOS Safari 11.0以上
- iOS Safari 9.0以上
- Firefox 60以上
- Microsoft Edge 18以上
- Android WebView
  - Google Chrome 39以上と互換性のあるバージョンに限る
  - Android WebView での動作には allow_webview オプションの設定が必要です。詳しくは [こちら](https://docs.repro.io/ja/dev/web/api.md) を参照してください。
- iOS WebView
  - iOS Safari 9.0以上と互換性のあるバージョンに限る
  - iOS WebView での動作には allow_webview オプションの設定が必要です。詳しくは [こちら](https://docs.repro.io/ja/dev/web/api.md) を参照してください。

##### NOTE
Internet Explorer は動作対象外となります。

アプリのWebViewを含む上記以外のブラウザではWeb SDKは動作を停止し、イベントのトラッキングやメッセージの表示など一切の機能が動かなくなります。
利用可能な機能は下記となります

| カテゴリ | 機能 | 動作対象ブラウザ |
| --- | --- | --- |
| データ収集 | 標準イベントトラッキング | ✔ |
| データ収集 | カスタムイベントトラッキング | ✔ |
| データ収集 | 標準ユーザープロフィール | ✔ |
| データ収集 | カスタムユーザープロフィール | ✔ |
| データ収集 | ユーザーID | ✔ |
| データ収集 | オプトアウト機能 | ✔ |
| データエクスポート | イベントデータエクスポート [※1](#steps-for-using-beta-or-optional-feature) | ✔ |
| データエクスポート | ユーザーIDエクスポート | ✔ |
| マーケティング | プッシュ通知 |  |
| マーケティング | Webメッセージ | ✔ |
| マーケティング | オーディエンス | ✔ |

### iOS

- 開発環境: Xcode 11以上
- 動作対象: iOS 10.0以上

利用可能な機能は下記となります

| カテゴリ | 機能 | iOS 10.0~ |
| --- | --- | --- |
| データ収集 | 標準イベントトラッキング | ✔ |
| データ収集 | カスタムイベントトラッキング | ✔ |
| データ収集 | 標準ユーザープロフィール | ✔ |
| データ収集 | カスタムユーザープロフィール | ✔ |
| データ収集 | ユーザーID | ✔ |
| データ収集 | オプトアウト機能 | ✔ |
| データ収集 | WebView(標準イベントトラッキング) | ✔ |
| データ収集 | WebView(カスタムイベントトラッキング) | ✔ |
| データ収集 | WebView(標準ユーザープロフィール) | ✔ |
| データ収集 | WebView(カスタムユーザープロフィール) | ✔ |
| データ収集 | WebView(ユーザーID) |  |
| データ収集 | WebView(オプトアウト機能) |  |
| データエクスポート | イベントデータエクスポート [※1](#steps-for-using-beta-or-optional-feature) | ✔ |
| データエクスポート | ユーザーIDエクスポート | ✔ |
| マーケティング | プッシュ通知 | ✔ |
| マーケティング | アプリ内メッセージ | ✔ |
| マーケティング | オーディエンス | ✔ |

### Android

- 開発環境: Android Studio 1.2以上 (推奨)
- 動作対象: Android 5.0以上

利用可能な機能は下記となります

| カテゴリ | 機能 | Android 5.0~ |
| --- | --- | --- |
| データ収集 | 標準イベントトラッキング | ✔ |
| データ収集 | カスタムイベントトラッキング | ✔ |
| データ収集 | 標準ユーザープロフィール | ✔ |
| データ収集 | カスタムユーザープロフィール | ✔ |
| データ収集 | ユーザーID | ✔ |
| データ収集 | オプトアウト機能 | ✔ |
| データ収集 | WebView(標準イベントトラッキング) | ✔ |
| データ収集 | WebView(カスタムイベントトラッキング) | ✔ |
| データ収集 | WebView(標準ユーザープロフィール) | ✔ |
| データ収集 | WebView(カスタムユーザープロフィール) | ✔ |
| データ収集 | WebView(ユーザーID) |  |
| データ収集 | WebView(オプトアウト機能) |  |
| データエクスポート | イベントデータエクスポート [※1](#steps-for-using-beta-or-optional-feature) | ✔ |
| データエクスポート | ユーザーIDエクスポート | ✔ |
| マーケティング | プッシュ通知 | ✔ |
| マーケティング | アプリ内メッセージ | ✔ |
| マーケティング | オーディエンス | ✔ |

### Unity

- 動作対象: Unity 5.2.0以上

利用可能な機能は下記となります

| カテゴリ | 機能 | iOS 10.0~ | Android 5.0~ |
| --- | --- | --- | --- |
| データ収集 | 標準イベントトラッキング | ✔ | ✔ |
| データ収集 | カスタムイベントトラッキング | ✔ | ✔ |
| データ収集 | 標準ユーザープロフィール |  |  |
| データ収集 | カスタムユーザープロフィール | ✔ | ✔ |
| データ収集 | ユーザーID | ✔ | ✔ |
| データ収集 | オプトアウト機能 | ✔ | ✔ |
| データ収集 | WebView(標準イベントトラッキング) |  |  |
| データ収集 | WebView(カスタムイベントトラッキング) |  |  |
| データ収集 | WebView(標準ユーザープロフィール) |  |  |
| データ収集 | WebView(カスタムユーザープロフィール) |  |  |
| データ収集 | WebView(ユーザーID) |  |  |
| データ収集 | WebView(オプトアウト機能) |  |  |
| データエクスポート | イベントデータエクスポート [※1](#steps-for-using-beta-or-optional-feature) | ✔ | ✔ |
| データエクスポート | ユーザーIDエクスポート | ✔ | ✔ |
| マーケティング | プッシュ通知 | ✔ | ✔ |
| マーケティング | アプリ内メッセージ | ✔ | ✔ |
| マーケティング | オーディエンス | ✔ | ✔ |

### Cordova

利用可能な機能は下記となります

| カテゴリ | 機能 | iOS 10.0~ | Android 5.0~ |
| --- | --- | --- | --- |
| データ収集 | 標準イベントトラッキング | ✔ | ✔ |
| データ収集 | カスタムイベントトラッキング | ✔ | ✔ |
| データ収集 | 標準ユーザープロフィール |  |  |
| データ収集 | カスタムユーザープロフィール | ✔ | ✔ |
| データ収集 | ユーザーID | ✔ | ✔ |
| データ収集 | オプトアウト機能 | ✔ | ✔ |
| データ収集 | WebView(標準イベントトラッキング) | 不要 | 不要 |
| データ収集 | WebView(カスタムイベントトラッキング) | 不要 | 不要 |
| データ収集 | WebView(標準ユーザープロフィール) | 不要 | 不要 |
| データ収集 | WebView(カスタムユーザープロフィール) | 不要 | 不要 |
| データ収集 | WebView(ユーザーID) | 不要 | 不要 |
| データ収集 | WebView(オプトアウト機能) | 不要 | 不要 |
| データエクスポート | イベントデータエクスポート [※1](#steps-for-using-beta-or-optional-feature) | ✔ | ✔ |
| データエクスポート | ユーザーIDエクスポート | ✔ | ✔ |
| マーケティング | プッシュ通知 | ✔ | ✔ |
| マーケティング | アプリ内メッセージ | ✔ | ✔ |
| マーケティング | オーディエンス | ✔ | ✔ |

### Monaca

利用可能な機能は下記となります

| カテゴリ | 機能 | iOS 10.0~ | Android 5.0~ |
| --- | --- | --- | --- |
| データ収集 | 標準イベントトラッキング | ✔ | ✔ |
| データ収集 | カスタムイベントトラッキング | ✔ | ✔ |
| データ収集 | 標準ユーザープロフィール |  |  |
| データ収集 | カスタムユーザープロフィール | ✔ | ✔ |
| データ収集 | ユーザーID | ✔ | ✔ |
| データ収集 | オプトアウト機能 | ✔ | ✔ |
| データ収集 | WebView(標準イベントトラッキング) | 不要 | 不要 |
| データ収集 | WebView(カスタムイベントトラッキング) | 不要 | 不要 |
| データ収集 | WebView(標準ユーザープロフィール) | 不要 | 不要 |
| データ収集 | WebView(カスタムユーザープロフィール) | 不要 | 不要 |
| データ収集 | WebView(ユーザーID) | 不要 | 不要 |
| データ収集 | WebView(オプトアウト機能) | 不要 | 不要 |
| データエクスポート | イベントデータエクスポート [※1](#steps-for-using-beta-or-optional-feature) | ✔ | ✔ |
| データエクスポート | ユーザーIDエクスポート | ✔ | ✔ |
| マーケティング | プッシュ通知 | ✔ | ✔ |
| マーケティング | アプリ内メッセージ | ✔ | ✔ |
| マーケティング | オーディエンス | ✔ | ✔ |

### Cocos2d-x

利用可能な機能は下記となります

| カテゴリ | 機能 | iOS 10.0~ | Android 5.0~ |
| --- | --- | --- | --- |
| データ収集 | 標準イベントトラッキング | ✔ | ✔ |
| データ収集 | カスタムイベントトラッキング | ✔ | ✔ |
| データ収集 | 標準ユーザープロフィール |  |  |
| データ収集 | カスタムユーザープロフィール | ✔ | ✔ |
| データ収集 | ユーザーID | ✔ | ✔ |
| データ収集 | オプトアウト機能 | ✔ | ✔ |
| データ収集 | WebView(標準イベントトラッキング) |  |  |
| データ収集 | WebView(カスタムイベントトラッキング) |  |  |
| データ収集 | WebView(標準ユーザープロフィール) |  |  |
| データ収集 | WebView(カスタムユーザープロフィール) |  |  |
| データ収集 | WebView(ユーザーID) |  |  |
| データ収集 | WebView(オプトアウト機能) |  |  |
| データエクスポート | イベントデータエクスポート [※1](#steps-for-using-beta-or-optional-feature) | ✔ | ✔ |
| データエクスポート | ユーザーIDエクスポート | ✔ | ✔ |
| マーケティング | プッシュ通知 | ✔ | ✔ |
| マーケティング | アプリ内メッセージ | ✔ | ✔ |
| マーケティング | オーディエンス | ✔ | ✔ |

### React Native

利用可能な機能は下記となります

| カテゴリ | 機能 | iOS 10.0~ | Android 5.0~ |
| --- | --- | --- | --- |
| データ収集 | 標準イベントトラッキング | ✔ | ✔ |
| データ収集 | カスタムイベントトラッキング | ✔ | ✔ |
| データ収集 | 標準ユーザープロフィール | ✔ | ✔ |
| データ収集 | カスタムユーザープロフィール | ✔ | ✔ |
| データ収集 | ユーザーID | ✔ | ✔ |
| データ収集 | オプトアウト機能 | ✔ | ✔ |
| データ収集 | WebView(標準イベントトラッキング) | ✔ | ✔ |
| データ収集 | WebView(カスタムイベントトラッキング) | ✔ | ✔ |
| データ収集 | WebView(標準ユーザープロフィール) | ✔ | ✔ |
| データ収集 | WebView(カスタムユーザープロフィール) | ✔ | ✔ |
| データ収集 | WebView(ユーザーID) |  |  |
| データ収集 | WebView(オプトアウト機能) |  |  |
| データエクスポート | イベントデータエクスポート [※1](#steps-for-using-beta-or-optional-feature) | ✔ | ✔ |
| データエクスポート | ユーザーIDエクスポート | ✔ | ✔ |
| マーケティング | プッシュ通知 | ✔ | ✔ |
| マーケティング | アプリ内メッセージ | ✔ | ✔ |
| マーケティング | オーディエンス | ✔ | ✔ |

### Flutter

利用可能な機能は下記となります

| カテゴリ | 機能 | iOS 10.0~ | Android 5.0~ |
| --- | --- | --- | --- |
| データ収集 | 標準イベントトラッキング | ✔ | ✔ |
| データ収集 | カスタムイベントトラッキング | ✔ | ✔ |
| データ収集 | 標準ユーザープロフィール | ✔ | ✔ |
| データ収集 | カスタムユーザープロフィール | ✔ | ✔ |
| データ収集 | ユーザーID | ✔ | ✔ |
| データ収集 | オプトアウト機能 | ✔ | ✔ |
| データ収集 | WebView(標準イベントトラッキング) | ✔ | ✔ |
| データ収集 | WebView(カスタムイベントトラッキング) | ✔ | ✔ |
| データ収集 | WebView(標準ユーザープロフィール) | ✔ | ✔ |
| データ収集 | WebView(カスタムユーザープロフィール) | ✔ | ✔ |
| データ収集 | WebView(ユーザーID) |  |  |
| データ収集 | WebView(オプトアウト機能) |  |  |
| データエクスポート | イベントデータエクスポート [※1](#steps-for-using-beta-or-optional-feature) | ✔ | ✔ |
| データエクスポート | ユーザーIDエクスポート | ✔ | ✔ |
| マーケティング | プッシュ通知 | ✔ | ✔ |
| マーケティング | アプリ内メッセージ | ✔ | ✔ |
| マーケティング | オーディエンス | ✔ | ✔ |

##### NOTE

- β機能やオプション機能をご利用される場合は、弊社営業、もしくはカスタマーサクセス担当までご連絡ください。

### 管理画面サポートブラウザ

下記ブラウザの最新版のみをサポートしています。

- [Google Chrome](https://www.google.com/chrome/browser/desktop/index.html)
- [Safari](https://www.apple.com/safari/)

---

## API

### Setup / ユーザーID



#### reproio('setup', *token*, *options*)

- token: string (必須)
  : - Reproの管理画面にある `SDKトークン` を設定してください。
- options: object



オプション:

| Key | Value | 説明 |
| --- | --- | --- |
| disable_ip_list | array (string) | 除外したいグローバルIPを設定できます。 *（e.g. ["111.111.1.1"]）* |
| log_level | string | "info", "warn", "error", "none" のいずれかが選択できます。 *(デフォルト: 'default')* |
| opt_out_by_default | boolean | "true", "false" のいずれかが選択できます。 *(デフォルト: false)* |
| silver_egg_uid_storage_key | string | シルバーエッグレコメンドメッセージのためのユーザーIDが登録されているCookieのキーを設定できます。 |
| allow_webview | boolean | WebViewだと判定される環境において、Repro Webの動作を許可するか設定できます。 |
| linker_domains | array (string) | 複数の異なるドメインにまたがってユーザーの情報を引き継ぐ設定ができます。 *（e.g. ["example.com"]）* 参考: [クロスドメイン・トラッキング機能](https://docs.repro.io/ja/dev/web/cross-domain-tracking.md) |
| disable_linker_params_referrer_check | boolean | クロスドメインとして設定された遷移元のデータを引き継ぐ際、まず `document.referrer` を確認してクロスドメインなトラッキングとみなしてよいかを判別します。 *(デフォルト: false)* 参考: [クロスドメイン・トラッキング機能](https://docs.repro.io/ja/dev/web/cross-domain-tracking.md) |
| disable_auto_attach_linker_params | boolean | クロスドメイン・トラッキング機能をオンにするとページ内のDOMに変化があった際に自動的に新規のaタグにもパラメータを付与しますが、このオプションを "true" に設定することでこの挙動を無効にできます。 *(デフォルト: false)* 参考: [クロスドメイン・トラッキング機能](https://docs.repro.io/ja/dev/web/cross-domain-tracking.md) |
| interval_days_to_storage_expiration | integer | ユーザーの識別子を含む、Cookieに保存している各種情報の保持日数 *(デフォルト: 730)* |
| session_expiry_interval | integer | あるイベントが発生した際に、その直前のイベントからどれくらいの時間が経過していれば新しいセッションとみなすかを決める時間（秒） *(デフォルト: 1800000 = 30分)* |
| spa_mode | string | [SPAモード](https://docs.repro.io/ja/dev/web/spa.md) を有効にします。ページ遷移時のイベントハンドリングが可能になります。有効な値は `'history'` , `'hash'` , `'none'` の3つです。 *(デフォルト: 'none')* |
| close_messages_on_pagechange | boolean | SPAモードのページ遷移時にメッセージを自動的に閉じます。 *(デフォルト: false)* |
| reuse_messages_on_pagechange | string | SPAモードにおいてメッセージを再利用し、毎回のページ遷移で表示可能にします。有効な値は `'unlimited'`, `'multitime'`, `'none'` です。`'unlimited'` では表示回数制限の全くないメッセージのみを再利用します。`'multitime'` の場合、複数回表示可能かつ１日あたりの回数制限のないメッセージを再利用します。この場合、同時に複数のブラウザやタブを利用しているケースではメッセージが表示回数以上に表示される可能性があります。 `'none'` の場合はメッセージの再利用を行わず、無制限表示のメッセージであっても一定間隔(標準で3分間隔)でしか表示されません。 *(デフォルト: 'none')* |
| close_messages_by_in_page_link | boolean | ページ内リンク(例: `<a href="#foo">`)をクリックした場合、表示中のメッセージをすべて閉じます。spa_mode が `hash` の場合は無視されます *(デフォルト: true)* |
| cookie_domain | string | Web SDKが記録するCookieのドメインを設定できます。省略された場合には、現在のサイトのドメインにおけるApexドメイン（ `shop.example.com` では `example.com` ）が利用されます。 |

例:

```html
<script>
    !function(o,e,n){var r=[];if(window.reproio)console.info("Repro Web SDK was loaded more than once");else{window.reproio=function(){r.push(arguments)};var i=o.createElement(e),t=o.getElementsByTagName(e)[0];i.src="https://cdn.reproio.com/web/v2/repro-sdk.min.js",i.async=!0,i.crossOrigin="",i.onload=function(){window.reproio("setSnippetVersion","2.1"),r.forEach(function(o){window.reproio.apply(window.reproio,o)})},t.parentNode.insertBefore(i,t)}}(document,"script");
    reproio("setup", "YOUR_REPRO_SDK_TOKEN");
</script>
```

参考:　[導入](https://docs.repro.io/ja/dev/web/getstarted/web.md)

#### reproio('setUserID', *userID*)

- userID: string (必須)
  : - ユーザーIDを設定してください。
    - setupの直前にセットするようにしてください。

```js-web
reproio("setUserID", "xxxxxxxxxxxx");
```

参考: [ユーザーID](https://docs.repro.io/ja/dev/web/user-id.md)

### イベントトラッキング

#### reproio('track', *name*, *properties*)

- name: string (必須)
  : - イベント名を設定してください。
    - `___repro___` から始まるイベント名は使用できません。
    - イベント名にnullや空文字列は不可、上限は191文字です。


- properties: object
  : - イベントの付帯情報としてプロパティを設定できます。
    - key: string
    - value: string | integer | double | date

例:

```js-web
// Custom event
reproio("track", "Finished tutorial");


// Custom event with properties
reproio("track", "user review", { rating: 3 });
```

参考: [イベントトラッキング](https://docs.repro.io/ja/dev/web/tracking.md)

#### reproio('trackAddPaymentInfo', *properties*)

- properties: object

プロパティ:

| Key | Value | 説明 |
| --- | --- | --- |
| content_id | string | 商品やページを示すID |
| content_category | string | 商品やページのカテゴリ |
| value | double | 商品の金額 |
| currency | string | valueに指定した値の通貨単位 |
| extras | object | カスタムプロパティ 詳細は [こちら](#web-extra-properties-api) |

例:

```js-web
reproio("trackAddPaymentInfo", {
  value: 8000.0,
  currency: "JPY",
  content_category: "Clothing & Shoes > Mens > Clothing",
  content_id: "1234"
});
```

参考: [イベントトラッキング](https://docs.repro.io/ja/dev/web/tracking.md)

#### reproio('trackAddToCart', *content_id*, *properties*)

- content_id: string (必須)
  : - 商品やページを示すIDを設定してください。
- properties: object

プロパティ:

| Key | Value | 説明 |
| --- | --- | --- |
| content_name | string | 商品やページの名前 |
| content_category | string | 商品やページのカテゴリ |
| value | double | 商品の金額 |
| currency | string | valueに指定した値の通貨単位 |
| extras | object | カスタムプロパティ 詳細は [こちら](#web-extra-properties-api) |

例:

```js-web
reproio("trackAddToCart", "1234", {
  value: 5000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing"
});
```

参考: [イベントトラッキング](https://docs.repro.io/ja/dev/web/tracking.md)

#### reproio('trackAddToWishlist', *properties*)

- properties: object

プロパティ:

| Key | Value | 説明 |
| --- | --- | --- |
| content_id | string | 商品やページを示すID |
| content_name | string | 商品やページの名前 |
| content_category | string | 商品やページのカテゴリ |
| value | double | 商品の金額 |
| currency | string | valueに指定した値の通貨単位 |
| extras | object | カスタムプロパティ 詳細は [こちら](#web-extra-properties-api) |

例:

```js-web
 reproio("trackAddToWishlist", {
  value: 5000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing",
  content_id: "1234"
});
```

参考: [イベントトラッキング](https://docs.repro.io/ja/dev/web/tracking.md)

#### reproio('trackCompleteRegistration', *properties*)

- properties: object

プロパティ:

| Key | Value | 説明 |
| --- | --- | --- |
| content_name | string | 商品やページの名前 |
| value | double | 商品の金額 |
| currency | string | valueに指定した値の通貨単位 |
| status | string | 登録状態 |
| extras | object | カスタムプロパティ 詳細は [こちら](#web-extra-properties-api) |

例:

```js-web
reproio("trackCompleteRegistration", {
  value: 8000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  status: "completed"
});
```

参考: [イベントトラッキング](https://docs.repro.io/ja/dev/web/tracking.md)

#### reproio('trackInitiateCheckout', *properties*)

- properties: object

プロパティ:

| Key | Value | 説明 |
| --- | --- | --- |
| content_id | string | 商品やページを示すID |
| content_name | string | 商品やページの名前 |
| content_category | string | 商品やページのカテゴリ |
| value | double | 商品の金額 |
| currency | string | valueに指定した値の通貨単位 |
| num_items | integer | 同一の商品の購入数 |
| extras | object | カスタムプロパティ 詳細は [こちら](#web-extra-properties-api) |

例:

```js-web
reproio("trackInitiateCheckout", {
  value: 8000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing",
  content_id: "1234"
});
```

参考: [イベントトラッキング](https://docs.repro.io/ja/dev/web/tracking.md)

#### reproio('trackLead', *properties*)

- properties: object

プロパティ:

| Key | Value | 説明 |
| --- | --- | --- |
| content_name | string | 商品やページの名前 |
| content_category | string | 商品やページのカテゴリ |
| value | double | 商品の金額 |
| currency | string | valueに指定した値の通貨単位 |
| extras | object | カスタムプロパティ 詳細は [こちら](#web-extra-properties-api) |

例:

```js-web
reproio("trackLead", {
  value: 8000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing"
});
```

参考: [イベントトラッキング](https://docs.repro.io/ja/dev/web/tracking.md)

#### reproio('trackPurchase\`, *content_id*, *value*, *currency*, *properties*)

- content_id: string (必須)
  : - 商品やページを示すIDを設定してください。
- value: double (必須)
  : - 商品の金額を設定してください。
- currency: string (必須)
  : - valueに指定した値の通貨単位を設定してください。
- properties: object

プロパティ:

| Key | Value | 説明 |
| --- | --- | --- |
| content_name | string | 商品やページの名前 |
| content_category | string | 商品やページのカテゴリ |
| num_items | integer | 同一の商品の購入数 |
| extras | object | カスタムプロパティ 詳細は [こちら](#web-extra-properties-api) |

例:

```js-web
reproio("trackPurchase", "1234", 8000.0, "JPY", {
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing",
  num_items: 2
});
```

参考: [イベントトラッキング](https://docs.repro.io/ja/dev/web/tracking.md)

#### reproio('trackSearch', *properties*)

- properties: object

プロパティ:

| Key | Value | 説明 |
| --- | --- | --- |
| content_id | string | 商品やページを示すID |
| content_category | string | 商品やページのカテゴリ |
| value | double | 商品の金額 |
| currency | string | valueに指定した値の通貨単位 |
| search_string | string | ユーザーが入力した検索文字列 |
| extras | object | カスタムプロパティ 詳細は [こちら](#web-extra-properties-api) |

例:

```js-web
reproio("trackSearch", {
  value: 3000.0,
  currency: "JPY",
  content_category: "Clothing & Shoes > Mens > Clothing",
  search_string: "Jeans",
  content_id: "1234"
});
```

参考: [イベントトラッキング](https://docs.repro.io/ja/dev/web/tracking.md)

#### reproio('trackShare', *properties*)

- properties: object

プロパティ:

| Key | Value | 説明 |
| --- | --- | --- |
| content_id | string | 商品やページを示すID |
| content_name | string | 商品やページの名前 |
| content_category | string | 商品やページのカテゴリ |
| service_name | string | サービスの名前 |
| extras | object | カスタムプロパティ 詳細は [こちら](#web-extra-properties-api) |

例:

```js-web
reproio("trackShare", {
  content_category: "Clothing & Shoes > Mens > Clothing",
  content_name: "Slim Jeans",
  content_id: "1234",
  service_name: "twitter"
});
```

参考: [イベントトラッキング](https://docs.repro.io/ja/dev/web/tracking.md)

#### reproio('trackViewContent', *content_id*, *properties*)

- content_id: string (必須)
  : - 商品やページを示すIDを設定してください。
- properties: object

プロパティ:

| Key | Value | 説明 |
| --- | --- | --- |
| content_name | string | 商品やページの名前 |
| content_category | string | 商品やページのカテゴリ |
| value | double | 商品の金額 |
| currency | string | valueに指定した値の通貨単位 |
| extras | object | カスタムプロパティ 詳細は [こちら](#web-extra-properties-api) |

例:

```js-web
reproio("trackViewContent", "1234", {
  value: 5000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing"
});
```

参考: [イベントトラッキング](https://docs.repro.io/ja/dev/web/tracking.md)

### ユーザープロフィール

#### reproio('setDateUserProfile', *key*, *value*)

- key: string (必須)
  : - `___repro___` から始まるイベント名は使用できません。
    - イベント名にnullや空文字列は不可、上限は255文字です。
- value: date (必須)

例:

```js-web
var now = new Date();
reproio("setDateUserProfile", "LastLogin", now);
```

参考: [ユーザープロフィール](https://docs.repro.io/ja/dev/web/user-profile.md)

#### reproio('setDoubleUserProfile', *key*, *value*)

- key: string (必須)
  : - `___repro___` から始まるイベント名は使用できません。
    - イベント名にnullや空文字列は不可、上限は255文字です。
- value: double (必須)

例:

```js-web
reproio("setDoubleUserProfile", "Height", 176.5);
```

参考: [ユーザープロフィール](https://docs.repro.io/ja/dev/web/user-profile.md)

#### reproio('setIntUserProfile', *key*, *value*)

- key: string (必須)
  : - `___repro___` から始まるイベント名は使用できません。
    - イベント名にnullや空文字列は不可、上限は255文字です。
- value: integer (必須)

例:

```js-web
reproio("setIntUserProfile", "Age", 25);
```

参考: [ユーザープロフィール](https://docs.repro.io/ja/dev/web/user-profile.md)

#### reproio('setStringUserProfile', *key*, *value*)

- key: string (必須)
  : - `___repro___` から始まるイベント名は使用できません。
    - イベント名にnullや空文字列は不可、上限は255文字です。
- value: string (必須)
  : - セットできる文字数の上限は255文字です。

例:

```js-web
reproio("setStringUserProfile", "Job", "Developer");
```

参考: [ユーザープロフィール](https://docs.repro.io/ja/dev/web/user-profile.md)

#### reproio('setUserEmailAddress', *value*)

- value: string (必須)

例:

```js-web
reproio("setUserEmailAddress", "user@example.com");
```

参考: [ユーザープロフィール](https://docs.repro.io/ja/dev/web/user-profile.md)

#### reproio('setUserGender', *value*)

- value: string (必須)
  : - 次の値を設定できます。: "male", "female", "other"

```js-web
// set the gender as "male"
reproio("setUserGender", "male");
// set the gender as "female"
reproio("setUserGender", "female");
// set the gender as "other"
reproio("setUserGender", "other");
```

参考: [ユーザープロフィール](https://docs.repro.io/ja/dev/web/user-profile.md)

### デバイスID

#### reproio('getDeviceID')

```js-web
reproio('getDeviceID');
```

参考: [デバイスID](https://docs.repro.io/ja/dev/web/device-id.md)

### オプトアウト機能

#### reproio('isOptedIn')

返り値：

| Value | 説明 |
| --- | --- |
| true | オプトイン状態を示します。 |
| false | オプトアウト状態を示します。 |
```js-web
reproio('isOptedIn');
```

参考: [オプトアウト機能](https://docs.repro.io/ja/dev/web/optout.md)

#### reproio('optIn')

```js-web
reproio('optIn');
```

参考: [オプトアウト機能](https://docs.repro.io/ja/dev/web/optout.md)

#### reproio('optOut')

```js-web
reproio('optOut');
```

参考: [オプトアウト機能](https://docs.repro.io/ja/dev/web/optout.md)

### クロスドメイン・トラッキング機能

#### reproio('updateLinkerParameters')

```js-web
reproio('updateLinkerParameters');
```

参考: [クロスドメイン・トラッキング機能](https://docs.repro.io/ja/dev/web/cross-domain-tracking.md)

### LINEユーザーIDの連携

#### reproio('linkLineID', *lineUserID*, *lineChannelID*)

- lineUserID: string (必須)
  : - LINEのユーザーIDを設定してください。
- lineChannelID: string (必須)
  : - LINEのチャネルIDを設定してください。

例:

```javascript
// Set user ID first
reproio('setUserID', 'user123');

// Link LINE User ID
reproio('linkLineID', 'LINE_USER_ID', 'LINE_CHANNEL_ID');
```

参考: [ReproへのLINEユーザーIDの登録 (Web SDK)](https://docs.repro.io/ja/dev/web/line-integration.md)

#### reproio('unlinkLineID', *lineUserID*, *lineChannelID*)

- lineUserID: string (必須)
  : - LINEのユーザーIDを設定してください。
- lineChannelID: string (必須)
  : - LINEのチャネルIDを設定してください。

例:

```javascript
reproio('unlinkLineID', 'LINE_USER_ID', 'LINE_CHANNEL_ID');
```

参考: [ReproへのLINEユーザーIDの登録 (Web SDK)](https://docs.repro.io/ja/dev/web/line-integration.md)

### その他

#### reproio('version')

現在の SDK のバージョンを返します。

---

## クロスドメイン・トラッキング機能

クロスドメイン・トラッキング機能を利用することで、あるWebサービスが複数のドメインにまたがってページを提供する場合に、複数のドメインをまたいでエンドユーザーの情報を引き継ぎ同一のユーザーとしてトラッキングするが可能になります。たとえば example.com というルートドメイン上で展開するサービスの一部が example.co.jp というルートドメインで提供され相互にリンクが存在する場合、example.com で動くReproのWeb SDKが記録しているエンドユーザーの情報を example.co.jp へ引き継ぎます。

なお mail.example.com から news.example.com へ遷移する場合はサブドメインは異なるもののルートドメインは同じ扱いになるためクロスドメインにはあたりません。このケースではクロスドメイン・トラッキング用の特別な設定は不要です。

### クロスドメイン・トラッキングが可能なケース

遷移元のドメインから遷移先のドメインに向いたリンク（<a> タグ）を辿ったとき。

##### NOTE
例:

- ショッピングサイト => ショッピングサイトが利用する決済システムへのリンク
- LP用別ドメイン => サイト本体へのリンク

### クロスドメイン・トラッキングが不可能なケース

- Formタグの送信を経由したページ遷移
- リダイレクトによる遷移
- リダイレクトを実施する（= リクエスト元に対してLocationヘッダつきのレスポンスを返してクライアントにリダイレクトを実施させる）サーバの実装によってはパラメータを引き継ぐこともありますが、サービス側のサーバの実装依存になるためサポートしておりません

### 設定時の注意事項

クロスドメイン・トラッキング機能の設定に不備があると意図しない形でユーザーのトラッキングがされてしまう可能性があるので、必ずHTML/JavaScriptの経験のある開発者が設定してください。

### 注意すべきケース

複数ドメインで展開する異なるサービスがそれぞれ個別にログイン機構があり、そういった複数ドメインをクロスドメインとしてトラッキングしたい場合（いわゆるマルチテナントと呼ばれるものがこれにあたります）、ユーザーの識別子などのデータは引き継ぎ元のデータが引き継ぎ先のデータを上書きしてしまうので、こういったケースで双方向に頻繁に行き来するサイトは設定に注意が必要です。

### 設定時の注意事項

[API](https://docs.repro.io/ja/dev/web/api.md) に記載の内容のうち、クロスドメイン・トラッキング機能に関連するものの詳細を説明します。

#### 1. linker_domains（必須）

`linker_domains` には対象ページからクロスドメインとしてトラッキングしたい遷移先ドメイン名を配列として入力してください。

```js-web
reproio("setup", "YOUR_REPRO_SDK_TOKEN", {
  linker_domains: ["blog.example.com", "shop.example.com"],
})
```

与えられたドメイン名が現在閲覧中のサイトのドメイン名と一致している場合は、クロスドメイン・トラッキングの設定から除外します。現在閲覧中のドメイン、リンク先のドメイン、 `linker_domains` オプションの値の組み合わせによるクロスドメイン・トラッキングの動作是非の詳細については、下記の表を参考にしてください。YESの場合はリンクにクロスドメイン・トラッキング用のパラメータが付与され、NOの場合は付与されません。



#### 2. disable_linker_params_referrer_check

ReproのWeb SDKがクロスドメインとして設定された遷移元のデータを引き継ぐ際、まず `document.referrer` を確認してクロスドメインなトラッキングとみなしてよいかを判別します。引き継ぐ際の条件として 、`linker_domains` のオプションに渡されたドメインと document.referrer のドメインが一致する必要があります。

`disable_linker_params_referrer_check` オプションを true に設定すると、先述の確認をスキップしクロスドメインなトラッキングとして動作します。この設定を有効にすると、 `document.referrer` が `linker_domains` に渡されたものと一致するかどうかにかかわらず遷移元のドメインからデータを引き継ぎます。

なおリファラのチェックを行う際においても `linker_domains` の表に記載した形で判定を行います。つまり、 `linker_domains: ['example.com']` と指定されていれば リファラが example.com や sub.example.com の場合には該当するとみなされます。

##### WARNING
この設定を利用する際の注意点

- パラメータ付きのリンクがSNSやチャットツールに貼られてしまった場合など、本来はクロスドメインなリンク遷移とは判定されない不正なケースにおいてもデータを引き継いでしまう可能性があります

```js-web
reproio("setup", "YOUR_REPRO_SDK_TOKEN", {
  linker_domains: ["blog.example.com", "shop.example.com"],
  disable_linker_params_referrer_check: true,
});
```

#### 3. disable_auto_attach_linker_params

Web SDKはページの読み込み時にページ内に存在するリンクをチェックしてクロスドメイン・トラッキング用のパラメータを付与するだけでなく、ページ内のDOMに変化があった際にも自動的に新規のaタグにパラメータを付与します。この挙動が望ましくない場合は `disable_auto_attach_linker_params` のオプションをtrueにすることでこの機能を無効化することができます。

```js-web
reproio("setup", "YOUR_REPRO_SDK_TOKEN", {
  linker_domains: ["blog.example.com", "shop.example.com"],
  disable_auto_attach_linker_params: true,
});
```

#### 4. updateLinkerParameters

Web SDKはページの読み込み時にページ内に存在するリンクをチェックしてクロスドメイン・トラッキング用のパラメータを付与します。セッション時間が比較的長いサービスや `disable_auto_attach_linker_params` オプションを利用しているケースなどでは、定期的にリンクに付与されたクロスドメイン・トラッキング用のパラメータを更新したいケースが想定されます。こういった場合においては `reproio('updateLinkerParameters');` を呼び出すことでaタグのリンクに付与された引き継ぎデータを最新化することができます。

```js-web
reproio("updateLinkerParameters");
```

---

## SPA(Single Page Application)サイトへの導入

SPA(Single Page Application)サイトにRepro Webを導入する方法について案内します。

### SPAサイトへ導入する

SPAサイトでの導入方法を説明します。

SPAに対応しているライブラリには、「ブラウザのHistory APIを利用するもの」と「 `onhashchange` イベントを利用するもの」の2つがあり、Repro Webはどちらにも対応しています。

#### SPAモードをオンにする

Web SDKの導入タグの `setup` 呼び出し部分に、次のように `spa_mode` というプロパティを追加することでSPAモードがオンになります。

**SPAモードをオンにする**

```js
reproio('setup', "YOUR_REPRO_SDK_TOKEN", { spa_mode: 'history' })
```

`spa_mode` の値には `'history'` , `'hash'` , `'none'` の3つが指定可能で、導入先のサイトがページをどの様に識別して表示しているかに応じて設定をする必要があります。
URLのパスもしくはクエリ文字列で指定している場合は `'history'` を、URLのハッシュで指定している場合は `'hash'` を指定してください。
`'none'` を指定するとSPAモードはオフになります。この場合、SPAではない通常のサイトにおけるRepro Webの動作と同じになります。

その他、SPAモードではいくつか追加のオプションがあります。 [setup API](https://docs.repro.io/ja/dev/web/api.md#api-setup-options) も参考にしてください。

### SPAモードで変わること

SPAモードをオンにすると、通常の動作や機能に加えて次のような挙動が実現されます。

- ページ遷移のたびに [イベントトリガー](https://docs.repro.io/ja/dashboard/setting/web-tracking-rule.md) に合致するイベントがトラックされます。
- ページ遷移のたびに、設定情報およびメッセージのリストを取得した最後の日時をチェックし、その日時から一定の時間が経過していればメッセージのリストを再取得します。再取得する間隔は3分になります。
- 任意のタイミングで処理を実行することのできるコールバック機能が利用できるようになります。

#### コールバック関数を登録する

次のような形でコールバック関数を登録することで、あらかじめ用意された次のタイミングにおいて任意の処理を実行するよう指定することができます。
この例ではSPAにおけるページ遷移のタイミングでブラウザのコンソールにログを出力しています。

**コールバック関数を登録する**

```js
reproio('on', 'pagechange', () => {
  console.log('page changed!');
})
```

`pagechange` の値部分には以下の2つが指定できます。

- `init` : 初回の設定情報の取得が完了したときにコールバックが実行されます。
- `pagechange` : SPAにおけるページ遷移を検知したときにコールバックが実行されます。

### SPAで構成されていないWebサイトでSPAモードをオンにする

SPAで構成されていないWebサイトでSPAモードをオンにした場合も、Repro Webは通常通り動作します。

SPAで構成されているが、特定のページのみSPAではないサイトでも、SPAモードをオンにしてください。

### SPAサイトでユーザーIDをセットする

通常のサイトと同じ様に導入スニペットが実行されるタイミングでユーザーIDが決定している場合は、 [通常の導入手順](https://docs.repro.io/ja/dev/web/getstarted/web.md#install-setup-measurement-tags) と同じく reproio("setup", "YOUR_REPRO_SDK_TOKEN"); よりも前に reproio('setUserID') を設定してください。

サイト読み込み後にログイン処理が行われるなど、後からユーザーIDが決定される場合は、その時点で reproio('setUserID') と再度 reproio('setup', 'YOUR_REPRO_SDK_TOKEN') を呼び出すようにする必要があります。

##### NOTE
setUserID を呼び出す際の挙動について：

- 同じユーザーIDで複数回呼び出された場合、リセット処理はスキップされ、既存のメッセージ表示状態が維持されます
- 異なるユーザーIDで呼び出された場合、内部状態がリセットされ、表示中のメッセージは閉じられます

サイト読み込み後にログイン処理を行い、ログインしたタイミングでコールバックを呼び出してユーザーIDをセットする場合のサンプルコードを提示します。

```js
// User.auth はサンプルです
User.auth(id, password, {
    // ログインに成功
    success: function(user) {

        // user.idにユーザーIDが入っていると仮定しています
        reproio("setUserID", user.id);
        reproio("setup", "YOUR_REPRO_SDK_TOKEN");

        // ログイン後の処理
        ...
    },
});
```

---

## Web設定

Repro Webに関するイベント条件を設定する画面です。
Web設定は、設定 > Web設定からアクセスできます



### イベントトリガー

イベントトリガーとは、特定のページにアクセスした時にイベントが実行されるように条件を設定することができます。
Webメッセージで新規に作成したイベントトリガーもWeb設定一覧に反映されます。

#### イベントトリガーを設定する

##### イベント



既存のイベントを選択するか、新しいイベントを入力してください。

すでにイベントトリガーが設定してあるイベントは、既存のイベントから選択できません。イベントに条件を追加したい場合は、イベントトリガーの編集画面から行ってください。



##### 条件



イベントをトラックする条件を決めます。ここで指定したすべての条件に合致するときイベントがトラックされます。

URL、ドメイン、パス、クエリパラメータ、リファラ、ページタイトルといったフィルターをつかって、トラック対象となるイベントの条件を指定できます。条件同士はANDのみで設定でき、最大20個まで組み合わせることができます。

複数のページで同一のイベントを設定したい場合は、OR条件を設定して下さい。赤枠内の条件を一括で削除したい場合は、イベントトリガーの削除で消すことができます。

| フィルター名 | 値の例 |
| --- | --- |
| ページURL | [https://repro.io/](https://repro.io/) |
| ドメイン | example.com |
| ページパス | /shop |
| クエリパラメータ | product_id=1 |
| リファラ | google.com |
| ページタイトル | Shop index |

##### NOTE
- トリガーで `ページURL` を指定し、条件に `等しい`／`等しくない` を指定した場合、値には `location.href` で指定されているURLと完全一致する値を入力しないとトラッキングされません。
- `正規表現に一致する` など、正規表現にもとづく条件を利用した場合、指定された値は `new RegExp()` の引数となり条件比較が行われます。正規表現の詳細な仕様については [MDNのドキュメント](https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Regular_Expressions) を参照してください。
- JavaScriptのオブジェクトに対してどのような比較が行われるかに関しては [イベントトリガー、Webメッセージの表示条件における値の扱いについて](https://docs.repro.io/ja/faq/web/object-compare.md) をご確認ください。

##### メモ

条件の説明・目的を記載してください。

---

## イベントトリガー、Webメッセージの表示条件における値の扱いについて

イベントトリガー、及びWebメッセージのトリガー条件の値として渡されたオブジェクトは、以下表のように評価し比較されます。
基本的には、条件の値としてNull、またはundefinedが渡ってくることはありません。「比較を行わない」と記載している場合、メッセージは表示されません。

| 指定した条件/オブジェクト | 文字列 | 数値 | Dateオブジェクト | null | undefined | NaN |
| --- | --- | --- | --- | --- | --- | --- |
| と一致する | 文字列として比較 | 文字列として比較 | 比較を行わない | 比較を行わない | 比較を行わない | 比較を行わない |
| と一致しない | 文字列として比較 | 文字列として比較 | 文字列として比較 | "null" という文字列として比較 | "undefined" という文字列として比較 | "NaN" という文字として比較 |
| 以上(数値) | parseFloat()の結果と比較 | parseFloat()の結果と比較 | 比較を行わない | 比較を行わない | 比較を行わない | 比較を行わない |
| 以下(数値) | parseFloat()の結果と比較 | parseFloat()の結果と比較 | 比較を行わない | 比較を行わない | 比較を行わない | 比較を行わない |
| を含む(文字列) | 文字列として比較 | 文字列として比較 | 比較を行わない | 比較を行わない | 比較を行わない | 比較を行わない |
| を含まない(文字列) | 文字列として比較 | 文字列として比較 | Dateオブジェクトとして比較 | 比較を行わない | 比較を行わない | 比較を行わない |
| 正規表現に一致 | 文字列として比較 | 文字列として比較 | 比較を行わない | 比較を行わない | 比較を行わない | 比較を行わない |
| 正規表現に一致(大文字と小文字の違いを無視) | 文字列として比較 | 文字列として比較 | 比較を行わない | 比較を行わない | 比較を行わない | 比較を行わない |
| 正規表現に一致しない | 文字列として比較 | 文字列として比較 | 比較を行わない | 比較を行わない | 比較を行わない | 比較を行わない |
| 正規表現に一致しない(大文字と小文字の違いを無視) | 文字列として比較 | 文字列として比較 | 比較を行わない | 比較を行わない | 比較を行わない | 比較を行わない |

---

## 導入

##### NOTE
ネイティブアプリのWebViewでSDKを動作させる場合は、 [こちら](https://docs.repro.io/ja/dev/sdk/webview.md) を実装し、Repro Webは導入しないようにしてください。

### Repro Webを導入する

Repro Webをサイトで利用できるようにするための手順を説明します。
 
本マニュアルに従って導入作業を進めてください。
 

#### 手順

- [アカウントにログインする](#setting-login-for-repro)
- [導入方法を選択する](#choose-deployment-method)
- [Google Tag Manager(GTM)で導入する](#install-with-gtm)
- [Webページに直接タグを埋め込み導入する](#install-directly-on-web-pages)



### アカウントにログインする

はじめにRepro Webの利用申し込みをするとご連絡いただいたメールアドレスへ招待メールが届きます。
メール内の「今すぐ確認」リンクから、Repro Webの管理画面へログインしてください。



すでに企業内で他のメンバーの方がRepro Webを利用している場合は、
Repro Web管理者権限を持つメンバーの方に 左メニューの設定 > メンバー管理 からメールアドレスを登録し、
アカウントへ招待していただく事もできます。



### 導入方法を選択する

Repro Webはタグマネージャーを使って導入することができます。

Repro WebではGoogle Tag Manager(GTM)とYahoo Tag Manager(YTM)の動作を確認していますが、
YTMは「タグの実行順序がコントロールできない」という問題があるため、
Google Tag Manager(GTM)での導入を推奨しています。

その他の計測タグマネージャーでも動作実績はございますが動作確認の上ご利用ください。

本マニュアルではGoogle Tag Manager(GTM)を使った場合とウェブページに直接埋め込む場合の導入方法をご紹介します。

[Google Tag Manager(GTM)で導入する](#install-with-gtm)
 
[Webページに直接タグを埋め込み導入する](#install-directly-on-web-pages)
 
 

また、以下の条件に該当する場合はサポート担当へお問合せ下さい。
適切な導入方法をご案内します。

- 複数ドメインをまたいで計測する
- ASPサービスやカートシステムを利用しているサイトへ導入する



### Google Tag Manager(GTM)で導入する

Google Tag Manager(以下GTM)を使ってRepro Webを導入する方法を説明します。

#### 目次

- [セットアップ計測タグを導入する](#install-setup-measurement-tags)
- [コンバージョン計測タグを導入する](#install-cv-measurement-tags)
- [イベント計測タグを導入する](#install-event-measurement-tags)
- [ユーザープロフィールを取得する](#get-user-profile)



### セットアップ計測タグを導入する

セットアップ計測タグはサイト上のRepro Webを利用する上で必須の設定項目です。
 
以下手順に沿って導入を進めてください。
 

#### セットアップ計測タグを準備する

サイトに設置するセットアップ計測タグを準備します。

まず、導入サイトでユーザーIDを取得するか否かをご判断下さい。

##### NOTE
ユーザーIDとは、Repro Webでユーザーを同定するための識別子です。
通常Repro Webはブラウザ(cookie)をベースにユーザーを同定しますが、異なるブラウザやプラットフォームを跨いでユーザを識別するためには、ユーザーIDにDB上の会員IDなど固有の識別子をセットする必要があります。

例えば、以下のようなケースを実現するためにはユーザーIDの設定が必要です。

- PC、スマホといったデバイスを跨いだ計測やセグメント施策を実施する場合
- WebとAppなどプラットフォームを跨いだ計測やセグメント施策を実施する場合
- 会員ID等をキーとしてDB、DMP等のサーバーデータとRepro Webを直接連携する場合

ECサイトなどログイン機能があるサイトではユーザーIDの設定を推奨します。
ユーザーIDを設定する場合、セットアップ計測タグに会員IDユーザ同定ができる値を動的に埋め込みます。
この作業は基礎的なプログラムの知識が必要ですので、サイト管理者様など、適切なご担当者様へ本マニュアルを連携し作業を進めてください。

以下、ユーザーIDを取得する場合は `ユーザーID実装あり` のタグを利用し、ユーザーIDを取得しない場合は `ユーザーID実装なし` のタグを利用してください。

**セットアップ計測タグ(ユーザーID実装あり)**

```html
// SET_USER_ID の部分に貴社のユーザーIDが取得できる実装をしてください
<script>
    !function(o,e,n){var r=[];if(window.reproio)console.info("Repro Web SDK was loaded more than once");else{window.reproio=function(){r.push(arguments)};var i=o.createElement(e),t=o.getElementsByTagName(e)[0];i.src="https://cdn.reproio.com/web/v2/repro-sdk.min.js",i.async=!0,i.crossOrigin="",i.onload=function(){window.reproio("setSnippetVersion","2.1"),r.forEach(function(o){window.reproio.apply(window.reproio,o)})},t.parentNode.insertBefore(i,t)}}(document,"script");
    reproio("setUserID", "SET_USER_ID");
    reproio("setup", "YOUR_REPRO_SDK_TOKEN");
    reproio("track","PageView");
</script>
```

**セットアップ計測タグ(ユーザーID実装なし)**

```html
<script>
   !function(o,e,n){var r=[];if(window.reproio)console.info("Repro Web SDK was loaded more than once");else{window.reproio=function(){r.push(arguments)};var i=o.createElement(e),t=o.getElementsByTagName(e)[0];i.src="https://cdn.reproio.com/web/v2/repro-sdk.min.js",i.async=!0,i.crossOrigin="",i.onload=function(){window.reproio("setSnippetVersion","2.1"),r.forEach(function(o){window.reproio.apply(window.reproio,o)})},t.parentNode.insertBefore(i,t)}}(document,"script");
   reproio("setup", "YOUR_REPRO_SDK_TOKEN");
   reproio("track","PageView");
</script>
```

次に、招待されたRepro Webの管理画面にログインし、 左メニューの設定 > プロジェクト設定 > 認証情報よりSDKトークンをコピーして下さい。



コピーしたSDKトークンの値をセットアップ計測タグ記述内の下から3行目、 `YOUR_REPRO_SDK_TOKEN` 部分に張り付けてください。

例えばSDKトークンが「asefpuh1jbnnvadi」の場合、以下のようになります。


Repro Webご利用のサイトがSPAとして構築されている場合、 [SPA(Single Page Application)サイトへの導入](https://docs.repro.io/ja/dev/web/spa.md) を参照してください。

以上でセットアップ計測タグの準備は完了です。

ユーザーIDを取得しない場合は、 [セットアップ計測タグを設置する](#setting-setup-tag) のステップへお進み下さい。

#### ユーザーIDを設定する

ユーザーID実装ありのセットアップ計測タグを設定した場合は、
セットアップ計測タグ記述内の指定部分( `SET_USER_ID` )に動的に会員ID等の値を埋め込んでください。

こちらの詳細な実施方法はGTMのドキュメントをご参照ください。
ここでは設定例をご紹介します。

まず、ログイン時、サイト上に [データレイヤー変数](https://support.google.com/tagmanager/answer/6164391?hl=ja) 等で会員IDを吐き出すようにしてください。

- 現在会員IDが吐き出されていない場合は軽微なサイト改修が必要です
- プログラムの基礎知識があるサイトご担当者様へ改修をご依頼下さい

次にGTMのユーザー定義変数としてサイト上の会員IDを登録します。


最後にセットアップ計測タグの所定箇所に二重波括弧で会員IDを埋め込みます。




#### セットアップ計測タグを設置する

準備したセットアップ計測タグをGTM経由でサイトに設置します。

GTMの管理画面にアクセスしていただき、以下の手順を行って下さい。

1. 左メニュー > タグ を選択して下さい
2. 新規ボタンをクリックして下さい



3.タグ名にはわかりやすい名前をつけてください。今回は「Repro Web SDK - setup」としています

4.タグの種類は `カスタムHTML` を選択して下さい

5.HTML部分に、セットアップ計測タグを準備する項目で作成したセットアップ計測タグをコピーしてペーストして下さい

6.詳細設定の下にある「タグ呼び出しオプション」を `１ページにつき１度` に設定して下さい



7.トリガーには計測対象全てのページで実行される `DOM Ready` を設定して下さい

- トリガーが存在しない場合、下記の手順でトリガーを新規作成してください

  1.「トリガー」の項目をクリックして下さい
  

  2.画面右上の「+」をクリックしてください
  
  3.トリガー名には、わかりやすい名前をつけてください。今回「DOM Ready」とします
   
  4.トリガーのタイプには `DOM Ready` を設定して下さい
   
  5.このトリガーの発生場所は `すべてのDOM Ready イベント` を選択して下さい
   
  6.保存をクリックして、トリガーを保存して下さい
   

  

#### セットアップ計測タグの動作確認をする

##### セットアップ計測タグの設置状況を確認する

セットアップ計測タグが設置されているかどうかを確認する場合は、公開ボタンの左隣の「プレビュー」ボタンを押下してください。

プレビュー押下後、設置サイトを閲覧するとサイト内で動作しているタグが確認できます。


##### Repro Webへデータが上がったか確認する

Repro Webが動作しているかを確認します。

左メニューのイベント > イベント設定 を確認してください。
 
ここに「PageView」が登録されていれば問題ありません。
 
 

**左メニューのイベント > イベント設定**


#### セットアップ計測タグの公開

GTMにて公開をクリックし、設定したセットアップ計測タグをサイトに反映させてください。



### コンバージョン計測タグを導入する

コンバージョン計測タグとは購入、予約、資料請求といったサイト成果を計測するためのタグです。

完了ページ等の成果地点で動作させることでサイト成果やその際の付帯情報を計測できます。

#### コンバージョン計測タグを準備する

##### コンバージョンのみを取得する場合

コンバージョン計測タグ記述内の `ここに~` 部分を管理画面へ反映させたい名称に差し替えてください。

**コンバージョン計測タグ**

```html
<script>
 reproio("track", "ここに「/complete 購入完了」のようなイベント名を入力してください");
</script>
```

##### コンバージョン付帯情報も取得する場合

例えばECサイトで、購入経験、前回購入日、前回購入金額、前回購入商品カテゴリ、といった値を等を取得する場合、購入完了時点で以下のような記述を行う事で取得可能です。

コンバージョン計測タグ記述内の `ここに~` 部分を管理画面へ反映させたい名称に差し替え、取得したい情報に応じて計測タグ内の記述を編集してください。

※埋め込む値はGTMの変数で用意する必要があります

**コンバージョン計測タグ(付帯情報を取得する場合)**

```html
<script>
 reproio("track", "ここに「/complete 購入完了」のようなイベント名を入力してください");
 reproio("setStringUserProfile", "購入経験", "あり");
 reproio("setDateUserProfile", "最終購入日", new Date());
 reproio("setIntUserProfile", "前回購入合計金額", "ここに動的に合計金額を埋め込んでください");
 reproio("setStringUserProfile", "前回購入商品カテゴリ", "ここに動的に商品カテゴリを埋め込んでください");
</script>
```

取得する値やその利用方法について相談したい場合は、Reproカスタマーサクセス担当までご連絡ください。

#### コンバージョン計測タグの設置

まずトリガーの設定をします。
 
以下、ページパスに「/complete」を含むページで購入完了コンバージョンを計測したい場合の例です。
 
 
1.トリガーを選択して下さい
 
2.新規ボタンをタップして下さい
 



3.トリガーのタイプに `DOM Ready` を選択して下さい
 
4. `一部のDOM Readyイベント` を設定して下さい
 
5.ページ発生イベントに 画像の様に `Page path` `含む` `/complete` を設定して下さい
 



次にタグの設定をします。

1.タグを選択して下さい
 
2.新規ボタンをタップして下さい
 



3.タグの種類に `カスタムHTML` を選択して下さい
 
4.コンバージョン計測タグの準備で作成した内容をHTMLの中に貼り付けて下さい
 



- 備考１：合計購入金額等、動的な値を取得する場合は事前にGTMのユーザー定義変数で値を用意し、コンバージョン計測タグの所定箇所に二重並み括弧"{{}}"で括って埋め込んでください。
- 備考２：この際、タグの詳細設定で以下2点の設定を忘れずに行ってください。
  - タグの呼び出しオプションを `1回のイベントにつき1度` を設定
  - タグの順序付けでコンバージョン計測タグが発効する前にセットアップ計測タグを配信するよう設定



最後に、先の手順で設定したコンバージョン計測用トリガーを選択し保存して、GTMを公開してください。

##### NOTE
空文字やnil、nullといった値を登録しようとすると、開発者ツールのコンソール上にエラーが出ます。
 
※ただし、これによってWebサイトやRepro Webの動作に影響がでたりはしません。
 
このエラーが出るのを回避する方法として、一例ですが、
 
if({{GTMの変数}}){reproio("track", {{GTMの変数}});}
 
というようにif文で条件分岐させる方法があります。
 
具体的な方法はプログラムの基礎知識がある方にてご検討ください。
 
また、付帯情報に設定できる値は255文字以下です。
 
255文字以上の値を取得したい場合は、値を分割して取得するといった対応をご検討ください。
 



### イベント計測タグを導入する

ページビューに加えてWebサイト上のユーザー行動を計測できます。

例えばカート投入クリック、特定要素の表示、といった行動を計測できます。

#### イベント計測タグを準備する

取得したいイベント名を `ここに~` の部分へ記述してください。

**イベント計測タグ**

```html
<script>
  reproio("track", "ここにイベント名を入力してください");
</script>
```

##### NOTE
空文字やnil、nullといった値を登録しようとすると、開発者ツールのコンソール上にエラーが出ます。
 
※ただし、これによってWebサイトやRepro Webの動作に影響がでたりはしません。
 
このエラーが出るのを回避する方法として、一例ですが、
 
if({{GTMの変数}}){reproio("track", {{GTMの変数}});}
 
というようにif文で条件分岐させる方法があります。
 
具体的な方法はプログラムの基礎知識がある方にてご検討ください。
 
また、付帯情報に設定できる値は255文字以下です。
 
255文字以上の値を取得したい場合は、値を分割して取得するといった対応をご検討ください。
 

#### イベント計測タグを設置する

まず、GTMのトリガーでイベントの発火条件を作成します。
 
以下、「カートに追加」という文字を含んだサイト要素のクリックを取得したい場合の例です。
 
 
1.トリガーを選択して下さい
 
2.新規ボタンをタップして下さい
 



3.トリガーのタイプに `クリック-すべての要素` を選択して下さい
 
4. `一部のクリック` を設定して下さい
 
5.ページ発生イベントに 画像の様に `Click Text` `含む` `カートに追加` を設定して下さい
 



その他GTMでは特定要素の表示、タイマー、スクロール、YouTube動画再生開始、等の様々なイベントを設定することができます。

次にタグの設定をします。

1.タグを選択して下さい
 
2.新規ボタンをタップして下さい
 



3.タグの種類に `カスタムHTML` を選択して下さい
 
4.コンバージョン計測タグの準備で作成した内容をHTMLの中に貼り付けて下さい
 



この際、タグの詳細設定で以下2点の設定を忘れずに行ってください。
 
- タグの呼び出しオプションを `1回のイベントにつき1度` を設定
- タグの順序付けでコンバージョン計測タグが発効する前にセットアップ計測タグを配信するよう設定



最後に、先の手順で設定したイベント計測用トリガーを選択し保存して、GTMを公開してください。

#### イベント計測タグの動作を確認する

左メニューのイベント > イベント設定 より取得したイベントが登録されているかを確認してください。



##### NOTE
空文字やnil、nullといった値を登録しようとすると、開発者ツールのコンソール上にエラーが出ます。
 
※ただし、これによってWebサイトやRepro Webの動作に影響がでたりはしません。
 
このエラーが出るのを回避する方法として、一例ですが、
 
if({{GTMの変数}}){reproio("track", {{GTMの変数}});}
 
というようにif文で条件分岐させる方法があります。
 
具体的な方法はプログラムの基礎知識がある方にてご検討ください。
 
また、付帯情報に設定できる値は255文字以下です。
 
255文字以上の値を取得したい場合は、値を分割して取得するといった対応をご検討ください。
 



### ユーザープロフィールを取得する

ユーザープロフィールとは、性別、年齢、地域、言語、会員種別といったユーザーの属性情報です。
 
ユーザープロフィールを取得する事で各ユーザー属性ごとの計測や施策を実施できます。
 

ユーザープロフィールを取得する方法としては以下2種類の方法があります。

[1.サイト上のデータをGTM経由で取得する](#obtain-via-gtm)
 
[2.自社DBやDMPからRepro Webへ直接APIでデータを連携する方法](#obtain-via-api)
 
 

設定する際には基礎的なプログラミング知識が必要な場合があります。
サイト管理者様等、適切な方へ本マニュアルを連携し作業を進めてください。



#### 1.サイト上のデータをGTM経由で取得する

##### ユーザープロフィール計測タグを準備する

ユーザープロフィール計測タグを設置し、所定箇所に取得したい値を埋め込んでください。

以下のタグの中から、取得するデータ型の種類に応じて適切なタグを利用してください。

**ユーザープロフィール計測タグ(文字列型)**

```html
<script>
  reproio("setStringUserProfile", "男女", "ここに値を埋め込んでください");
  reproio("setStringUserProfile", "会員ランク", "ここに値を埋め込んでください");
  reproio("setStringUserProfile", "ログイン状態", "ここに値を埋め込んでください");
  reproio("setStringUserProfile", "ニックネーム", "ここに値を埋め込んでください");
</script>
```

**ユーザープロフィール計測タグ(整数型)**

```html
<script>
  reproio("setIntUserProfile", "年齢", "ここに値を埋め込んでください");
  reproio("setIntUserProfile", "保有ポイント残高", "ここに値を埋め込んでください");
</script>
```

**ユーザープロフィール計測タグ(日付型)**

```html
<script>
  reproio("setDateUserProfile", "会員登録日", "ここに値を埋め込んでください");
  reproio("setDateUserProfile", "お誕生日", "ここに値を埋め込んでください");
</script>
```

##### ユーザープロフィール計測タグを設置する

準備したユーザープロフィール計測タグをGTMで設置します。

まず、GTMのトリガーでイベントの発火条件を作成します。

例えば、ログイン状態(≒「ID+8桁数字」の会員IDがサイトに吐き出されている時)のページビューで会員情報を取得したい場合は、下記のような設定となります。

1.トリガーを選択して下さい
 
2.新規ボタンをタップして下さい
 



3.トリガーのタイプに `ページビュー` を選択して下さい
 
4. `一部のページビュー` を設定して下さい
 
5.ページ発生イベントに 画像の様に `会員ID` `先頭が一致` `ID` を設定して下さい
 



次にタグの設定をします。

1.タグを選択して下さい
 
2.新規ボタンをタップして下さい
 



3.タグの種類に `カスタムHTML` を選択して下さい
 
4.先程用意したユーザープロフィール計測タグをカスタムHTMLで貼り付けてください
 
動的に取得する変数はあらかじめGTMのユーザー定義変数として用意し埋め込んでください
 



この際、タグの詳細設定で以下2点の設定を忘れずに行ってください。

- タグの呼び出しオプションを `1回のイベントにつき1度` を設定
- タグの順序付けでユーザープロフィール計測タグが発効する前にセットアップ計測タグを配信するよう設定



最後に、先の手順で設定したイベント計測用トリガーを選択し保存して、GTMを公開してください。



#### 2.自社DBやDMPからRepro Webへ直接APIでデータを連携する方法

はじめに、この方法はセットアップ計測タグでのユーザーID設定が必須です。

サイト上に存在する情報だけでなく自社のデータベースにのみ保持しているユーザーの属性情報を、直接ユーザープロフィールに登録できます。

このAPIを利用して更新したユーザープロフィールの情報を基にして、対象となるユーザーを絞り込んだメッセージを送信することができます。

APIの種類が4つありますので、Reproサポート担当と相談し適切なAPIを選んでください。

- [ユーザープロフィールバルクインポート](https://docs.repro.io/ja/dev/user-profile-bulk-import-api/index.md)
- [ユーザープロフィールAPI](https://docs.repro.io/ja/dev/user-profile-api/index.md)
- [オーディエンスAPI](https://docs.repro.io/ja/dev/audience-api/index.md)
- [オーディエンスインポート(β)](https://docs.repro.io/ja/dev/audience-import/index.md)

#### ユーザープロフィール取得の動作確認方法

登録されたユーザープロフィールは、左メニューのユーザープロフィール > ユーザープロフィール設定 に表示されます。

こちらで正しくデータが反映されているかを確認してください。

**Repro Web管理画面 > 左メニューのユーザープロフィール > ユーザープロフィール設定**


尚、取得された値が意図通りであるかどうかについては、左メニューのアナリティクス > アクセス分析 のフィルターより所定の値をクリックしてご確認をお願いします。



##### NOTE
空文字やnil、nullといった値を登録しようとすると、開発者ツールのコンソール上にエラーが出ます。
 
※ただし、これによってWebサイトやRepro Webの動作に影響がでたりはしません。
 
このエラーが出るのを回避する方法として、一例ですが、
 
if({{GTMの変数}}){reproio("track", {{GTMの変数}});}
 
というようにif文で条件分岐させる方法があります。
 
具体的な方法はプログラムの基礎知識がある方にてご検討ください。
 
また、付帯情報に設定できる値は255文字以下です。
 
255文字以上の値を取得したい場合は、値を分割して取得するといった対応をご検討ください。
 



### Webページに直接タグを埋め込み導入する

Webページに直接Repro Webのタグを埋め込む導入方法を説明します。

#### 目次

- [セットアップ計測タグを導入する](#install-setup-measurement-tags-2)
- [コンバージョン計測タグの導入](#install-cv-measurement-tags-2)
- [イベント計測タグの導入](#install-event-measurement-tags-2)
- [ユーザープロフィールを取得する](#get-user-profile-2)



### セットアップ計測タグを導入する

Repro Webを利用する上で必須の設定項目です。
 
以下手順に沿って導入を進めてください。
 

#### セットアップ計測タグを準備する

サイトに設置するセットアップ計測タグを準備します。

まず、導入サイトでユーザーIDを取得するか否かをご判断下さい。

##### NOTE
ユーザーIDとは、Repro Webでユーザーを同定するための識別子です。
通常Repro Webはブラウザ(cookie)をベースにユーザーを同定しますが、異なるブラウザやプラットフォームを跨いでユーザを識別するためには、ユーザーIDにDB上の会員IDなど固有の識別子をセットする必要があります。

例えば、以下のようなケースを実現するためにはユーザーIDの設定が必要です。

- PC、スマホといったデバイスを跨いだ計測やセグメント施策を実施する場合
- WebとAppなどプラットフォームを跨いだ計測やセグメント施策を実施する場合
- 会員ID等をキーとしてDB、DMP等のサーバーデータとRepro Webを直接連携する場合

ECサイトなどログイン機能があるサイトではユーザーIDの設定を推奨します。
ユーザーIDを設定する場合、計測タグに会員IDユーザ同定ができる値を動的に埋め込みます。
この作業は基礎的なプログラムの知識が必要ですので、サイト管理者様など、適切なご担当者様へ本マニュアルを連携し作業を進めてください。

以下、ユーザーIDを取得する場合は `ユーザーID実装あり` のタグを利用し、
ユーザーIDを取得しない場合は `ユーザーID実装なし` のタグを利用してください。

**セットアップ計測タグ(ユーザーID実装あり)**

```html
// SET_USER_ID の部分に貴社のユーザーIDが取得できる実装をしてください
<script>
    !function(o,e,n){var r=[];if(window.reproio)console.info("Repro Web SDK was loaded more than once");else{window.reproio=function(){r.push(arguments)};var i=o.createElement(e),t=o.getElementsByTagName(e)[0];i.src="https://cdn.reproio.com/web/v2/repro-sdk.min.js",i.async=!0,i.crossOrigin="",i.onload=function(){window.reproio("setSnippetVersion","2.1"),r.forEach(function(o){window.reproio.apply(window.reproio,o)})},t.parentNode.insertBefore(i,t)}}(document,"script");
    reproio("setUserID", "SET_USER_ID");
    reproio("setup", "YOUR_REPRO_SDK_TOKEN");
    reproio("track","PageView");
</script>
```

**セットアップ計測タグ(ユーザーID実装なし)**

```html
<script>
   !function(o,e,n){var r=[];if(window.reproio)console.info("Repro Web SDK was loaded more than once");else{window.reproio=function(){r.push(arguments)};var i=o.createElement(e),t=o.getElementsByTagName(e)[0];i.src="https://cdn.reproio.com/web/v2/repro-sdk.min.js",i.async=!0,i.crossOrigin="",i.onload=function(){window.reproio("setSnippetVersion","2.1"),r.forEach(function(o){window.reproio.apply(window.reproio,o)})},t.parentNode.insertBefore(i,t)}}(document,"script");
   reproio("setup", "YOUR_REPRO_SDK_TOKEN");
   reproio("track","PageView");
</script>
```

次に、招待されたRepro Webの管理画面にログインし、左メニューの設定 > プロジェクト設定 > 認証情報よりSDKトークンをコピーし下さい。



コピーしたSDKトークンの値をセットアップ計測タグ記述内の、
`YOUR_REPRO_SDK_TOKEN` 部分に張り付けてください。

Repro Webご利用のサイトがSPAとして構築されている場合、 [SPA(Single Page Application)サイトへの導入](https://docs.repro.io/ja/dev/web/spa.md) を参照してください。

以上でセットアップ計測タグの準備は完了です。

#### セットアップ計測タグを設置する

セットアップ計測タグを計測対象サイト全てのページビューで発火するように設置してください。

セットアップ計測タグはサイトのheadタグへの挿入をお願いします。

ユーザーID実装ありのセットアップ計測タグを設定する場合は、
セットアップ計測タグ記述内の指定部分(`SET_USER_ID` )に動的に会員ID等の値を埋め込んでください。

#### セットアップ計測タグの動作を確認する

イベント一覧に「PageView」が登録されているかご確認ください。

**左メニューのイベント > イベント設定**




### コンバージョン計測タグの導入

コンバージョン計測タグとは購入、予約、資料請求といったサイト成果を計測するためのタグです。

完了ページ等の成果地点で動作させることでサイト成果やその際の付帯情報を計測できます。

#### コンバージョン計測タグを準備する

##### コンバージョンのみを取得する

コンバージョン計測タグ記述内の `ここに~` 部分を管理画面へ反映させたい名称に差し替えてください。

**コンバージョン計測タグ**

```html
<script>
 reproio("track", "ここに「/complete 購入完了」のようなイベント名を入力してください");
</script>
```

##### コンバージョンと一緒に付帯情報も取得する

例えばECサイトで、購入経験、前回購入日、前回購入金額、前回購入商品カテゴリ、
といった値を等を取得する場合、購入完了時点で以下のような記述を行う事で取得可能です。

コンバージョン計測タグ記述内の `ここに~` 部分を管理画面へ反映させたい名称に差し替え、
取得したい値を埋め込むようにした上で、成果地点でタグを動作させてください。

**コンバージョン計測タグ(付帯情報を取得する場合)**

```html
<script>
 reproio("track", "ここに「/complete 購入完了」のようなイベント名を入力してください");
 reproio("setStringUserProfile", "購入経験", "あり");
 reproio("setDateUserProfile", "最終購入日", new Date());
 reproio("setIntUserProfile", "前回購入合計金額", "ここに動的に合計金額を埋め込んでください");
 reproio("setStringUserProfile", "前回購入商品カテゴリ", "ここに動的に商品カテゴリを埋め込んでください");
</script>
```

#### コンバージョン計測タグを設置する

準備したタグをheadもしくはbody内で発火するように設定してください。

また、このタグは必ずセットアップ計測タグより後に動作するよう、
HTML内でセットアップ計測タグより下方に設置する様にしてください。

取得する値や利用方法について相談したい場合は、
Reproカスタマーサクセス担当までご連絡ください。

##### NOTE
空文字やnil、nullといった値を登録しようとすると、開発者ツールのコンソール上にエラーが出ます。
 
※ただし、これによってWebサイトやRepro Webの動作に影響がでたりはしません。
 
このエラーが出るのを回避する方法として、一例ですが、
 
if({{GTMの変数}}){reproio("track", {{GTMの変数}});}
 
というようにif文で条件分岐させる方法があります。
 
具体的な方法はプログラムの基礎知識がある方にてご検討ください。
 
また、付帯情報に設定できる値は255文字以下です。
 
255文字以上の値を取得したい場合は、値を分割して取得するといった対応をご検討ください。
 



### イベント計測タグの導入

ページビュー以外のWebサイトにおけるユーザーの行動をトラックできます。

例えばカート投入クリックアクション、特定要素の表示などがあげられます。

#### イベント計測タグを設置する

`ここに~` の部分を取得したいイベント名に書き換え、イベントを取得したいタイミングで以下のタグを動作させてください。

また、このタグは必ずセットアップ計測タグより後に動作するよう、設置してください。

**イベント計測タグ**

```html
<script>
  reproio("track", "ここにイベント名を入力してください");
</script>
```

尚、GoogleTagManager(GTM)ではリンクのクリックや特定要素の出現、といったイベント計測が容易に設定できます。

複数のイベントを同時に取得する場合、以下のように<script>タグ内に、取得するイベントをまとめて記述してください。

**複数のイベント計測タグ**

```html
<script>
  reproio("track", "ここにイベント1を入力してください");
  reproio("track", "ここにイベント2を入力してください");
</script>
```

#### イベント計測タグの動作確認方法

左メニューのイベント > イベント設定 より取得したイベントが登録されているかを確認してください。



##### NOTE
空文字やnil、nullといった値を登録しようとすると、開発者ツールのコンソール上にエラーが出ます。
 
※ただし、これによってWebサイトやRepro Webの動作に影響がでたりはしません。
 
このエラーが出るのを回避する方法として、一例ですが、
 
if({{GTMの変数}}){reproio("track", {{GTMの変数}});}
 
というようにif文で条件分岐させる方法があります。
 
具体的な方法はプログラムの基礎知識がある方にてご検討ください。
 
また、付帯情報に設定できる値は255文字以下です。
 
255文字以上の値を取得したい場合は、値を分割して取得するといった対応をご検討ください。
 



### ユーザープロフィールを取得する

ユーザープロフィールとは、性別、年齢、地域、言語、会員種別などのユーザー属性情報です。
 
ユーザープロフィールを利用して各ユーザー属性ごとの計測や施策を実施できます。
 

ユーザープロフィールを取得する方法としては以下2種類の方法があります。

[1.サイトからユーザープロフィール計測タグで取得する](#obtain-via-web)
 
[2.自社DBやDMPからRepro Webへ直接APIでデータを連携する](#obtain-via-api-2)
 
 

設定する際には基礎的なプログラミング知識が必要な場合があります。
サイト管理者様等、適切な方へ本マニュアルを連携し作業を進めてください。



#### 1.サイトからユーザープロフィール計測タグで取得する

ユーザープロフィール計測タグを設置し、所定箇所に取得したい値を埋め込んでください。

以下のタグの中から取得するデータ型の種類に応じて適切なタグを利用してください。

また、このタグは必ずセットアップ計測タグより後に動作するよう、
HTML内でセットアップ計測タグより下方に設置する様にしてください。

**ユーザープロフィール取得タグ(文字列型)**

```html
<script>
  reproio("setStringUserProfile", "男女", "ここに値を埋め込んでください");
</script>
```

**ユーザープロフィール取得タグ(整数型)**

```html
<script>
  reproio("setIntUserProfile", "購入金額", "ここに値を埋め込んでください");
</script>
```

**ユーザープロフィール取得タグ(日付型)**

```html
<script>
  reproio("setDateUserProfile", "最終購入日", ココにnew Date()等の値を埋め込んでください);
</script>
```



#### 2.自社DBやDMPからRepro Webへ直接APIでデータを連携する

はじめに、この方法はセットアップ計測タグでのユーザーID設定が必須です。

サイト上に存在する情報だけでなく自社のデータベースにのみ保持しているユーザーの属性情報を、
直接ユーザープロフィールに登録できます。

このAPIを利用して更新したユーザープロフィールの情報を基にして、
対象となるユーザーを絞り込んだメッセージを送信することができます。

APIの種類が4つありますので、Reproサポート担当と相談し適切なAPIを選んでください。

- [ユーザープロフィールバルクインポート](https://docs.repro.io/ja/dev/user-profile-bulk-import-api/index.md)
- [ユーザープロフィールAPI](https://docs.repro.io/ja/dev/user-profile-api/index.md)
- [オーディエンスAPI](https://docs.repro.io/ja/dev/audience-api/index.md)
- [オーディエンスインポート(β)](https://docs.repro.io/ja/dev/audience-import/index.md)

#### ユーザープロフィール取得の動作確認方法

登録されたユーザープロフィールは、左メニューのユーザープロフィール > ユーザープロフィール設定 に表示されます。

こちらで正しくデータが反映されているかを確認してください。

**左メニューのユーザープロフィール > ユーザープロフィール設定**



尚、取得された値が意図通りであるかどうかについては、左メニューのアナリティクス > アクセス分析 のフィルターより所定の値をクリックしてご確認をお願いします。



##### NOTE
空文字やnil、nullといった値を登録しようとすると、開発者ツールのコンソール上にエラーが出ます。
 
※ただし、これによってWebサイトやRepro Webの動作に影響がでたりはしません。
 
このエラーが出るのを回避する方法として、一例ですが、
 
if({{GTMの変数}}){reproio("track", {{GTMの変数}});}
 
というようにif文で条件分岐させる方法があります。
 
具体的な方法はプログラムの基礎知識がある方にてご検討ください。
 
また、付帯情報に設定できる値は255文字以下です。
 
255文字以上の値を取得したい場合は、値を分割して取得するといった対応をご検討ください。
 

### 最後に

以上でRepro Webの導入は完了です。ご設定ありがとうございました。

メッセージを配信する場合は、 左メニューのマーケティング > メッセージ の画面から設定を行ってください。

---

## WebView

ネイティブアプリのWebViewで表示するWebページ内で、JavaScriptを使ってイベントをトラックしたりユーザープロフィールの設定をすることが出来ます。

##### WARNING
- 本ドキュメントは、iOS SDKまたはAndroid SDKを導入された方向けのWebViewの利用方法です。Web SDKを導入している方は [WebViewでの動作について](https://docs.repro.io/ja/dev/web/webview.md) をご確認ください。

##### NOTE
- iOSの `SFSafariViewController` には対応していません
- Unity、Cocos2d-xアプリ内のWebViewには対応していません。
- CordovaおよびMonacaでWebページを表示する場合は、本ページの実装は不要です。

WebViewでReproの機能を利用するために、以下の設定が必要になります。

- [WebViewでReproの利用を有効にする](/ja/dev/sdk/webview.html#webviewrepro)
- [Webページにトラッキングコードを追加する](/ja/dev/sdk/webview.html#web)

### WebViewでReproの利用を有効にする

まずはWebViewのイベントトラッキングおよびユーザープロフィールの設定を有効にします。有効にする方法はiOSとAndroidで対応方法が異なるので、それぞれ説明します。

#### iOS

`WKWebView` にセットするdelegateオブジェクトを渡します。

以下のサンプルでは `MyViewController` が `WKNavigationDelegate` を実装しているので、 `MyViewController` のインスタンスである `self` を `startWebViewTracking` の引数として渡します。

```objc
@interface MyViewController () <WKNavigationDelegate>

- (void)viewDidLoad
{
    [super viewDidLoad];

    WKWebView *webView = [[WKWebView alloc] init];

    ...

    [Repro startWebViewTracking:self];
    webView.navigationDelegate = self;
}
```

```swift
class MyViewController: WKNavigationDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        let webView = WKWebView()

        ...

        Repro.startWebViewTracking(delegate: self)
        self.webView.navigationDelegate = self
    }
```

```java
// This section explains the implementation in iOS.
// Please change the language to Objective-C or Swift.
```

```kotlin
// This section explains the implementation in iOS.
// Please change the language to Objective-C or Swift.
```

```js-react-native
// This section explains the implementation in iOS.
// Please change the language to Objective-C or Swift.
```

```dart
// This section explains the implementation in android.
// Please change the language to Objective-C or Swift.
```

##### WARNING
WKWebView.navigationDelegate へのインスタンスセットより前に startWebViewTracking: を実行してください。

設定が完了したら [Webページにトラッキングコードを追加する](/ja/dev/sdk/webview.html#web) へ進んでください。

#### Android

WebViewでイベントトラッキングおよびユーザープロフィールの設定を行うには、WebView自身とWebViewにセットするWebViewClientを `startWebViewTracking()` に渡します。WebViewClientはnullとすることも可能です。

```objc
// This section explains the implementation in android.
// Please change the language to java or kotlin.
```

```swift
// This section explains the implementation in android.
// Please change the language to java or kotlin.
```

```java
import android.webkit.WebView;
import android.webkit.WebViewClient;
import io.repro.android.Repro;

public class MyActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        WebView webView = (WebView)findViewById(R.id.webView);
        WebViewClient client = /* your WebViewClent object or null */;
        // webView.setWebViewClient(client); **Avoid implementing this line**

        // call startWebViewTracking() with webView and client
        Repro.startWebViewTracking(webView, client);

        // (Optional) You must specify "utf-8" as default encoding if you track events included localized strings
        webView.getSettings().setDefaultTextEncodingName("utf-8");
    }
}
```

```kotlin
import android.webkit.WebView
import android.webkit.WebViewClient
import io.repro.android.Repro

class MyActivity : Activity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val webView = findViewById<WebView>(R.id.webView)
        val client: WebViewClient? = /* your WebViewClient object or null */
        // webView.webViewClient = client  // Avoid implementing this line

        // call startWebViewTracking() with webView and client
        Repro.startWebViewTracking(webView, client)

        // (Optional) You must specify "utf-8" as default encoding if you track events included localized strings
        webView.settings.defaultTextEncodingName = "utf-8"
    }
}
```

```js-react-native
// This section explains the implementation in android.
// Please change the language to java or kotlin.
```

```dart
// This section explains the implementation in android.
// Please change the language to java or kotlin.
```

##### WARNING
`startWebViewTracking()` では、その内部において `WebView.setWebViewClient()` が実行されます。したがって、 `WebViewClient` を独自に実装した場合においても明示的に `WebView.setWebViewClient()` を行うことは避けてください。

##### WARNING
`startWebViewTracking()` より後に `WebView.setWebViewClient()` を実行した場合、本機能が無効となりますのでご注意ください。

##### WARNING
Android 9 Pie以降のOSでHTTP通信を行う場合、HTTP通信を許可するドメインを明示的に指名する必要があります。
詳しくは、 [Android 9 PieでHTTPページのWebviewのトラッキングができない](https://docs.repro.io/ja/faq/app/webview/1.md) をご参考ください。

設定が完了したら [Webページにトラッキングコードを追加する](/ja/dev/sdk/webview.html#web) へ進んでください。

#### React Native

React Native の WebView は `react-native-webview` のみ対応しています。

`react-native-webview` の `onShouldStartLoadWithRequest` で Repro の `handleWebViewUrl` に `request.url` を渡してください。

次に、 `originWhitelist` に `'repro://*'` を追加してください。

以下にサンプルコードを提示します。

```objc
// This section explains the implementation in React Native.
// Please change the language to JavaScript(React Native).
```

```swift
// This section explains the implementation in React Native.
// Please change the language to JavaScript(React Native).
```

```java
// This section explains the implementation in React Native.
// Please change the language to JavaScript(React Native).
```

```kotlin
// This section explains the implementation in React Native.
// Please change the language to JavaScript(React Native).
```

```js-react-native
render() {
    return <WebView
        source={{ uri: 'https://somewebsite_that_loads_repro.js' }}
        style={{ flex: 1 }}
        originWhitelist={['https://*', 'repro://*']}
        onShouldStartLoadWithRequest={ (request) => {
            if (Repro.handleWebViewUrl(request.url)) {
                return false;
            }
            ... optional other custom code ...

            return true;
        }}
    />
}
```

```dart
// This section explains the implementation in React Native.
// Please change the language to JavaScript(React Native).
```

設定が完了したら [Webページにトラッキングコードを追加する](/ja/dev/sdk/webview.html#web) へ進んでください。

#### Flutter

Flutter の WebView は `webview_flutter` と `flutter_inappwebview` に対応しています。また、 `webview_flutter` と `flutter_inappwebview` は実装方法が違うためご注意ください。

`webview_flutter` のサンプルコードは以下の通りです。 `setJavaScriptMode` に `JavaScriptMode.unrestricted` を設定してください。

次に、 `addJavaScriptChannel` を追加して `onMessageReceived` で受け取った `data.message` を `handleWebViewUrl` に渡してください。

```objc
// This section explains the implementation in Flutter.
// Please change the language to Dart.
```

```swift
// This section explains the implementation in Flutter.
// Please change the language to Dart.
```

```java
// This section explains the implementation in Flutter.
// Please change the language to Dart.
```

```kotlin
// This section explains the implementation in Flutter.
// Please change the language to Dart.
```

```js-react-native
// This section explains the implementation in Flutter.
// Please change the language to Dart.
```

```dart
// WebViewControllerの初期化
final controller = WebViewController()
  ..setJavaScriptMode(JavaScriptMode.unrestricted);

// JavaScriptチャンネルの追加
controller.addJavaScriptChannel(
  Repro.WEBVIEW_FLUTTER_CHANNEL_NAME,
  onMessageReceived: (JavaScriptMessage data) {
    Repro.handleWebViewUrl(data.message);
  },
);

// WebViewWidgetの作成
WebViewWidget(controller: controller)
```

`flutter_inappwebview` のサンプルコードは以下の通りです。 `shouldOverrideUrlLoading` で Repro の `handleWebViewUrl` に `navigationAction.request.url.toString()` を渡してください。

```objc
// This section explains the implementation in Flutter.
// Please change the language to Dart.
```

```swift
// This section explains the implementation in Flutter.
// Please change the language to Dart.
```

```java
// This section explains the implementation in Flutter.
// Please change the language to Dart.
```

```kotlin
// This section explains the implementation in Flutter.
// Please change the language to Dart.
```

```js-react-native
// This section explains the implementation in Flutter.
// Please change the language to Dart.
```

```dart
InAppWebView(
  // ...
  shouldOverrideUrlLoading: (controller, navigationAction) async {
    if (Repro.handleWebViewUrl(navigationAction.request.url.toString())) {
      return NavigationActionPolicy.CANCEL;
    }
    // optional other custom code ...

    return NavigationActionPolicy.ALLOW;
  },
  // ...
)
```

設定が完了したら [Webページにトラッキングコードを追加する](/ja/dev/sdk/webview.html#web) へ進んでください。

### Webページにトラッキングコードを追加する

WebViewで表示したページでイベントトラッキングやユーザープロフィールの設定を行うためにはReproのJavaScriptライブラリrepro.jsをページに読み込み、トラッキングコードを実装します。

#### JavaScriptライブラリrepro.jsを読み込む

HTMLファイルから、ReproのJavaScriptライブラリrepro.jsを読み込みます。イベントトラッキングやユーザープロフィールの設定を行いたいページに下記を追記してください。

```html
<head>
  ...
  <script src="//cdn.reproio.com/js/v8/repro.js" type="text/javascript" charset="utf-8"></script>
  ...
</head>
```

##### NOTE
アプリ内の [WebViewでReproの利用を有効にしている](/ja/dev/sdk/webview.html#webviewrepro) 場合に限り、repro.jsはWebView側で呼び出されたトラッキングコードの処理をアプリのRepro SDKを通してReproに送信します。
repro.jsはReproと直接通信を行わないため、単一では動作しません。

**ロードしたrepro.jsを動作しないようにする**

本機能を有効にしていないWebViewやブラウザからHTMLを開く場合は、 `isInAppBrowser` フラグを利用してrepro.jsが動作しないようにしてください。 `isInAppBrowser` に `false` を指定するとrepro.jsは動作しません。 `isInAppBrowser` の初期値は `true` です。

以下のサンプルでは、アプリが送信するユーザーエージェントの値を正規表現でチェックし、その結果を `isInAppBrowser` に設定しています。正規表現に一致するユーザーエージェントをアプリ側で指定することにより、そのアプリのWebViewで開かれた時のみrepro.jsが動作するようになります。

```html
<head>
  ...
  <script>
    // enable repro.js only when loading this HTML by your app's WebView
    window.repro = window.repro || {};
    window.repro.isInAppBrowser = /MY_CUSTOM_USER_AGENT/.test(navigator.userAgent);
  </script>
  <script src="//cdn.reproio.com/js/v8/repro.js" type="text/javascript" charset="utf-8"></script>
  ...
</head>
```

アプリ側でユーザーエージェントを指定する方法については以下を参考にしてください。

- [WebViewのユーザーエージェントをカスタマイズする (iOS)](https://docs.repro.io/ja/dev/sdk/webview/custom-ua-ios.md)
- [WebViewのユーザーエージェントをカスタマイズする (Android)](https://docs.repro.io/ja/dev/sdk/webview/custom-ua-android.md)

#### トラッキングコードを実装する

**イベントトラッキング（WebView）**

repro.jsが読み込まれたページにてイベントトラッキングを実装します。

以下にサンプルコードを提示します。

```html
<script>
  repro.track("PageView");
</script>
```

WebViewでのイベントトラッキングの実装についての詳細は、 [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md) を参考のうえ、 JavaScript(WebView)にコードを切り替えてご確認ください。

**ユーザープロフィール（WebView）**

repro.jsが読み込まれたページにてユーザープロフィールを実装します。

##### WARNING
- WebViewにてユーザープロフィールの設定を行うには、iOS SDK 5.19.0 以上 および Android SDK 5.18.0 以上を導入し、かつ [バージョン6以上のrepro.js](/ja/dev/sdk/webview.html#web) を利用する必要があります。

以下にサンプルコードを提示します。

```html
<script>
  repro.setStringUserProfile("Job", "Developer");
</script>
```

WebViewでのユーザープロフィールの実装についての詳細は、 [ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md) を参考のうえ、 JavaScript(WebView)にコードを切り替えてご確認ください。

---

## WebViewでの動作について

##### WARNING
- 本ドキュメントは、Web SDKを導入された方向けのWebViewの利用方法です。iOS SDKまたはAndroid SDKを導入している方は [WebView](https://docs.repro.io/ja/dev/sdk/webview.md) をご確認ください。

### Web SDK側の設定

次のように `allow_webview` オプションを利用することで、アプリ内WebViewにおいて Repro Web の動作を有効化することができます。

```js-web
reproio('setup', 'YOUR_REPRO_SDK_TOKEN', { allow_webview: true });
```

参考: [API](https://docs.repro.io/ja/dev/web/api.md)

### アプリ側の実装 - 必要な設定

WebView内でRepro Webが正しく動作するためには、アプリ側の設定も必要なケースが存在します。下記ドキュメントを参照のうえ、Repro Webをご利用いただくプラットフォームならびにWebViewの種類などに応じて適切な設定を行っていただくようお願いします。なお各プラットフォームにおけるAPIや設定の詳細は各プラットフォームのドキュメントを参照してください。

#### Android (WebView)

- `setJavaScriptEnabled` を true にしてください。
- `setDomStorageEnabled` を true にしてください。

#### Android (Chrome Custom Tab)

特別な設定は必要ありません。

##### WARNING
注意点

- エンドユーザの環境によっては Chrome 以外のブラウザで表示される可能性があります。この場合、Repro WebがサポートしていないブラウザではRepro Webは一切動作しません。
- Chromeアプリとセッションを共有するため、同一端末でアプリとブラウザのデバイスIDが同じになるケースがあります。

#### iOS (WKWebView)

- `javaScriptEnabled` を true にしてください。

##### WARNING
注意点

- 各コンポーネントに対して異なる `WKWebsiteDataStore` を設定している場合はCookieが共有されず、同一ユーザーIDが設定されないとコンポーネント毎に違うユーザーとして識別されるケースがあります。
- 各コンポーネント毎に異なる `WKWebsiteDataStore` を設定している場合、CookieとlocalStorageが異なるWebViewの間に共有されず、WebViewコンポーネント毎に新しいユーザーとして登録されるケースがあります。

#### iOS (UIWebView)

特別な設定は必要ありません。

##### WARNING
注意点

- `WKWebView` と違い、複数コンポーネントがあってもCookieは共有されるため、同一ユーザーとして識別されます。
- iOS11以降でSafariとCookieを共有したい場合は、`SFAuthenticationSession` を利用する必要があります。

#### iOS (SafariView)

- `javaScriptEnabled` を true にしてください。

##### WARNING
注意点

- `WKWebView` と違い、複数コンポーネントがあってもCookieは共有されるため、同一ユーザーとして識別されます。

---

## Android 9 PieでHTTPページのWebviewのトラッキングができない

Android 9 Pie以降のOSでHTTP通信を行う場合、
HTTP通信を許可するドメインを明示的に指名する必要があります。

以下の設定をアプリで行ってください。

### ネットワーク セキュリティ構成ファイルを追加する

**AndroidManifest.xml** に以下の記述を追加して、ネットワーク セキュリティ構成ファイルをアプリが読み込むように設定してください。

<!-- コメント: 途中に...を入れているため、XMLとしてBlockを指定できない。そのため一旦noneで指定する -->
```

<manifest ... >
    <application android:networkSecurityConfig="@xml/network_security_config"
                    ... >
        ...
    </application>
</manifest>
```

### HTTP通信を許可するドメインを記載する

`res/xml/network_security_config.xml` に以下のように、HTTP通信を許可するドメインを記載してください。

```xml

<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">cdn.reproio.com</domain>
        <domain includeSubdomains="true"> ... </domain>
    </domain-config>
</network-security-config>
```

---

## WebViewのユーザーエージェントをカスタマイズする (iOS)

NSUserDefaultsの `UserAgent` キーを使ってユーザーエージェントをカスタマイズできます。なお、カスタマイズはアプリケーション起動中に一度だけ実行してください。また、UIWebViewおよびWKWebViewのインスタンスが生成される前に実行してください。

以下は、オリジナルのユーザーエージェントの先頭に `MY_CUSTOM_USER_AGENT` という文字列を加えるサンプルです。

```objc
// get original UserAgent string by using temporal UIWebView
UIWebView *tmp = [[UIWebView alloc] init];
NSString *originalUA = [tmp stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"];

// create custom UserAgent string
NSString *customUA = [NSString stringWithFormat:@"%@ %@", @"MY_CUSTOM_USER_AGENT", originalUA];

// set custom UserAgent as default
NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:customUA , @"UserAgent", nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:dictionary];
```

```swift
// get original UserAgent string by using temporal UIWebView
let tmp = UIWebView()
let originalUA = tmp.stringByEvaluatingJavaScript(from: "navigator.userAgent")!

// create custom UserAgent string
let customUA = "MY_CUSTOM_USER_AGENT \(originalUA)"

// set custom UserAgent as default
UserDefaults.standard.register(defaults: ["UserAgent": customUA])
```

---

## WebViewのユーザーエージェントをカスタマイズする (Android)

WebSettingsの [setUserAgentStringメソッド](https://developer.android.com/reference/android/webkit/WebSettings.html#setUserAgentString(java.lang.String)) を使ってユーザーエージェントをカスタマイズできます。

以下は、オリジナルのユーザーエージェントの先頭に `MY_CUSTOM_USER_AGENT` という文字列を加えるサンプルです。

```java
final WebSettings settings = webView.getSettings();
settings.setUserAgentString("MY_CUSTOM_USER_AGENT " + settings.getUserAgentString());
```

---

## イベントトラッキング

アプリにおけるユーザーの行動をトラックできます。例えば以下のようなものがあげられます。

- ページの閲覧
- カートに追加
- 商品の購入
- ソーシャル・ネットワークへシェア

トラックされたイベントは分析機能のローデータとして使われます。また、プッシュ通知やメッセージを作成する際に、対象ユーザーをセグメントする条件としても利用できます。

イベントには付帯情報としてプロパティを指定できます。1つのイベントには最大20個のプロパティを指定可能です。

##### WARNING
- イベント設定数の上限はお客様のReproの契約プランによって異なります。無料プランの上限数はデフォルトで50件、有料プランの場合はデフォルトで200件です。
- イベント名を自動生成した場合、組み合わせが増えてすぐに上限に達しますので、ご注意ください。なお、現在のイベント設定数は **設定 > イベント設定** で確認することができます。
- HTMLアプリ内メッセージでのユーザープロフィールの設定を行うには、iOS SDK 5.19.0 以上 および Android SDK 5.18.0 以上を利用する必要があります。

##### NOTE
- プロパティー名はnullや空文字列は不可、上限は48文字です。
- プロパティの値には文字列、または数値をセットできます。
- プロパティの値が文字列の場合は上限191文字です。
- プロパティの値が数値の場合は `NaN(Not a Number)` および `Infinity` はセットできません。



### 標準イベント

Reproではユーザーの行動分析を行う上で典型的なイベントを **標準イベント** として定義しています。 **標準イベント** をトラックする際はユーザーの行動に応じたAPIを呼び出してください。また、アプリ独自のイベントをトラックする際は [カスタムイベント](#custom-event) をご利用ください。

##### WARNING
- トラッキングしたイベントをアプリ内メッセージの配信トリガーに利用する場合、アプリの画面描画サイクルを鑑みた実装を行う必要があります。 [アプリ内メッセージ](https://docs.repro.io/ja/dev/sdk/in-app-message.md#in-app-message-show-timing) を参照し、実装タイミングを調節してください。
- アプリ内メッセージの配信トリガーとして利用できない場合でも、イベントをトラッキングし、計測することはできます。

以下の表は標準イベントのプロパティの一覧です。イベントによって指定できるプロパティが異なります。詳細は各APIの説明を参照してください。

| プロパティ名 | 説明 | 型 |
| --- | --- | --- |
| content_id | 商品やページを示すID | string |
| content_name | 商品やページの名前 | string |
| content_category | 商品やページのカテゴリ | string |
| value | 商品の金額 | double |
| currency | valueに指定した値の通貨単位 | string |
| num_items | 同一の商品の購入数 | integer |
| search_string | ユーザーが入力した検索文字列 | string |
| status | 登録状態 | string |

##### NOTE
- 必須でないプロパティは省略可能です。
- アプリ独自のプロパティを追加したい場合は [独自プロパティの追加](#extra-properties) をご確認ください。

#### 閲覧

コンテンツの閲覧操作をトラックします。

**使用例**

- ユーザーが商品詳細画面を表示したとき

**プロパティ**

- content_id (**必須**、メソッドの第1引数に指定)
- content_name
- content_category
- value
- currency

```objc
RPRViewContentProperties *properties = [[RPRViewContentProperties alloc] init];

properties.value = 5000.0;
properties.currency = @"JPY";
properties.contentName = @"Slim Jeans";
properties.contentCategory = @"Clothing & Shoes > Mens > Clothing";

[Repro trackViewContent:@"1234" properties:properties];
```

```swift
import Repro.RPREventProperties

...

let properties = RPRViewContentProperties()

properties.value = 5000.0
properties.currency = "JPY"
properties.contentName = "Slim Jeans"
properties.contentCategory = "Clothing & Shoes > Mens > Clothing"

Repro.trackViewContentEvent(contentID: "1234", properties: properties)
```

```java
import io.repro.android.tracking.ViewContentProperties;

...

ViewContentProperties properties = new ViewContentProperties();

properties.setValue(5000.0);
properties.setCurrency("JPY");
properties.setContentName("Slim Jeans");
properties.setContentCategory("Clothing & Shoes > Mens > Clothing");

Repro.trackViewContent("1234", properties);
```

```kotlin
import io.repro.android.tracking.ViewContentProperties

...

val properties = ViewContentProperties()

properties.value = 5000.0
properties.currency = "USD"
properties.contentName = "JPY"
properties.contentCategory = "Clothing & Shoes > Mens > Clothing"

Repro.trackViewContent("1234", properties)
```

```cpp
#include "ReproCpp.h"

...

repro::ViewContentProperties properties;

properties.setContentName("Slim Jeans");
properties.setContentCategory("Clothing & Shoes > Mens > Clothing");
properties.setValue(5000.0);
properties.setCurrency("JPY");

ReproCpp::trackViewContent("1234", &properties);
```

```csharp
ViewContentProperties properties = new ViewContentProperties();

properties.SetContentName ("Slim Jeans");
properties.SetContentCategory ("Clothing & Shoes > Mens > Clothing");
properties.SetValue (5000.0);
properties.SetCurrency ("JPY");

Repro.TrackViewContent ("1234", properties);
```

```js-cordova
Repro.trackViewContent("1234", {
  value: 5000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing"
});
```

```js-react-native
Repro.trackViewContent("1234", {
  value: 5000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing"
});
```

```js-webview
repro.trackViewContent("1234", {
  value: 5000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing"
});
```

```js-inapp
Repro.trackViewContent("1234", {
  value: 5000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing"
});
```

```dart
await Repro.trackViewContent("1234", {
  "value": 5000.0,
  "currency": "JPY",
  "content_name": "Slim Jeans",
  "content_category": "Clothing & Shoes > Mens > Clothing"
});
```

#### 検索

検索する操作をトラックします。

**使用例**

- ユーザーが「検索」ボタンをタップしたとき

**プロパティ**

- content_id
- content_category
- value
- currency
- search_string

```objc
RPRSearchProperties *properties = [[RPRSearchProperties alloc] init];

properties.value = 3000.0;
properties.currency = @"JPY";
properties.contentCategory = @"Clothing & Shoes > Mens > Clothing";
properties.searchString = @"Jeans";
properties.contentID = @"1234";

[Repro trackSearch:properties];
```

```swift
import Repro.RPREventProperties

...

let properties = RPRSearchProperties()

properties.value = 3000.0
properties.currency = "JPY"
properties.contentCategory = "Clothing & Shoes > Mens > Clothing"
properties.searchString = "Jeans"
properties.contentID = "1234"

Repro.trackSearchEvent(properties: properties)
```

```java
import io.repro.android.tracking.SearchProperties;

...

SearchProperties properties = new SearchProperties();

properties.setValue(3000.0);
properties.setCurrency("JPY");
properties.setContentCategory("Clothing & Shoes > Mens > Clothing");
properties.setSearchString("Jeans");
properties.setContentId("1234");

Repro.trackSearch(properties);
```

```kotlin
import io.repro.android.tracking.SearchProperties

...

val properties = SearchProperties()

properties.value = 3000.0;
properties.currency = "JPY"
properties.contentCategory = "Clothing & Shoes > Mens > Clothing"
properties.searchString = "Jeans"
properties.contentId = "1234"

Repro.trackSearch(properties)
```

```cpp
#include "ReproCpp.h"

...

repro::SearchProperties properties;

properties.setContentId("1234");
properties.setContentCategory("Clothing & Shoes > Mens > Clothing");
properties.setValue(5000.0);
properties.setCurrency("JPY");
properties.setSearchString("Jeans");

ReproCpp::trackSearch(&properties);
```

```csharp
SearchProperties properties = new SearchProperties();

properties.SetContentID ("1234");
properties.SetContentCategory ("Clothing & Shoes > Mens > Clothing");
properties.SetValue (5000.0);
properties.SetCurrency ("JPY");
properties.SetSearchString ("Jeans");

Repro.TrackSearch (properties);
```

```js-cordova
Repro.trackSearch({
  value: 3000.0,
  currency: "JPY",
  content_category: "Clothing & Shoes > Mens > Clothing",
  search_string: "Jeans",
  content_id: "1234"
});
```

```js-react-native
Repro.trackSearch({
  value: 3000.0,
  currency: "JPY",
  content_category: "Clothing & Shoes > Mens > Clothing",
  search_string: "Jeans",
  content_id: "1234"
});
```

```js-webview
repro.trackSearch({
  value: 3000.0,
  currency: "JPY",
  content_category: "Clothing & Shoes > Mens > Clothing",
  search_string: "Jeans",
  content_id: "1234"
});
```

```js-inapp
Repro.trackSearch({
  value: 3000.0,
  currency: "JPY",
  content_category: "Clothing & Shoes > Mens > Clothing",
  search_string: "Jeans",
  content_id: "1234"
});
```

```dart
await Repro.trackSearch({
  "value": 3000.0,
  "currency": "JPY",
  "content_category": "Clothing & Shoes > Mens > Clothing",
  "search_string": "Jeans",
  "content_id": "1234"
});
```

#### カートに追加

カートに追加する操作をトラックします。

**使用例**

- ユーザーが「カートに入れる」ボタンをタップしたとき

**プロパティ**

- content_id (**必須**、メソッドの第1引数に指定)
- content_name
- content_category
- value
- currency

```objc
RPRAddToCartProperties *properties = [[RPRAddToCartProperties alloc] init];

properties.value = 5000.0;
properties.currency = @"JPY";
properties.contentName = @"Slim Jeans";
properties.contentCategory = @"Clothing & Shoes > Mens > Clothing";

[Repro trackAddToCart:@"1234" properties:properties];
```

```swift
import Repro.RPREventProperties

...

let properties = RPRAddToCartProperties()

properties.value = 5000.0
properties.currency = "JPY"
properties.contentName = "Slim Jeans"
properties.contentCategory = "Clothing & Shoes > Mens > Clothing"

Repro.trackAddToCartEvent(contentID: "1234", properties: properties)
```

```java
import io.repro.android.tracking.AddToCartProperties;

...

AddToCartProperties properties = new AddToCartProperties();

properties.setValue(5000.0);
properties.setCurrency("JPY");
properties.setContentName("Slim Jeans");
properties.setContentCategory("Clothing & Shoes > Mens > Clothing");

Repro.trackAddToCart("1234", properties);
```

```kotlin
import io.repro.android.tracking.AddToCartProperties

...

val properties = AddToCartProperties()

properties.value = 5000.0
properties.currency = "JPY"
properties.contentName = "Slim Jeans"
properties.contentCategory = "Clothing & Shoes > Mens > Clothing"

Repro.trackAddToCart("1234", properties)
```

```cpp
#include "ReproCpp.h"

...

repro::AddToCartProperties properties;

properties.setContentName("Slim Jeans");
properties.setContentCategory("Clothing & Shoes > Mens > Clothing");
properties.setValue(5000.0);
properties.setCurrency("JPY");

ReproCpp::trackAddToCart("1234", &properties);
```

```csharp
AddToCartProperties properties = new AddToCartProperties();

properties.SetContentName("Slim Jeans");
properties.SetContentCategory("Clothing & Shoes > Mens > Clothing");
properties.SetValue(5000.0);
properties.SetCurrency("JPY");

Repro.TrackAddToCart ("1234", properties);
```

```js-cordova
Repro.trackAddToCart("1234", {
  value: 5000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing"
});
```

```js-react-native
Repro.trackAddToCart("1234", {
  value: 5000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing"
});
```

```js-webview
repro.trackAddToCart("1234", {
  value: 5000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing"
});
```

```js-inapp
Repro.trackAddToCart("1234", {
  value: 5000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing"
});
```

```dart
await Repro.trackAddToCart("1234", {
  "value": 5000.0,
  "currency": "JPY",
  "content_name": "Slim Jeans",
  "content_category": "Clothing & Shoes > Mens > Clothing"
});
```

#### ウィッシュリストに追加

ウィッシュリストに商品を追加する操作をトラックします。

**使用例**

- ユーザーが「ウィッシュリストに入れる」ボタンをタップしたとき

**プロパティ**

- content_id
- content_name
- content_category
- value
- currency

```objc
RPRAddToWishlistProperties *properties = [[RPRAddToWishlistProperties alloc] init];

properties.value = 5000.0;
properties.currency = @"JPY";
properties.contentName = @"Slim Jeans";
properties.contentCategory = @"Clothing & Shoes > Mens > Clothing";
properties.contentID = @"1234";

[Repro trackAddToWishlist:properties];
```

```swift
import Repro.RPREventProperties

...

let properties = RPRAddToWishlistProperties()

properties.value = 5000.0
properties.currency = "JPY"
properties.contentName = "Slim Jeans"
properties.contentCategory = "Clothing & Shoes > Mens > Clothing"
properties.contentID = "1234"

Repro.trackAddToWishlistEvent(properties: properties)
```

```java
import io.repro.android.tracking.AddToWishlistProperties;

...

AddToWishlistProperties properties = new AddToWishlistProperties();

properties.setValue(5000.0);
properties.setCurrency("JPY");
properties.setContentName("Slim Jeans");
properties.setContentCategory("Clothing & Shoes > Mens > Clothing");
properties.setContentId("1234");

Repro.trackAddToWishlist(properties);
```

```kotlin
import io.repro.android.tracking.AddToWishlistProperties

...

val properties = AddToWishlistProperties()

properties.value = 5000.0
properties.currency = "JPY"
properties.contentName = "Slim Jeans"
properties.contentCategory = "Clothing & Shoes > Mens > Clothing"
properties.contentId = "1234"

Repro.trackAddToWishlist(properties)
```

```cpp
#include "ReproCpp.h"

...

repro::AddToWishlistProperties properties;

properties.setContentId("1234");
properties.setContentName("Slim Jeans");
properties.setContentCategory("Clothing & Shoes > Mens > Clothing");
properties.setValue(5000.0);
properties.setCurrency("JPY");

ReproCpp::trackAddToWishlist(&properties);
```

```csharp
AddToWishlistProperties properties = new AddToWishlistProperties();

properties.SetContentID("1234");
properties.SetContentName("Slim Jeans");
properties.SetContentCategory("Clothing & Shoes > Mens > Clothing");
properties.SetValue(5000.0);
properties.SetCurrency("JPY");

Repro.TrackAddToWishlist (properties);
```

```js-cordova
Repro.trackAddToWishlist({
  value: 5000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing",
  content_id: "1234"
});
```

```js-react-native
Repro.trackAddToWishlist({
  value: 5000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing",
  content_id: "1234"
});
```

```js-webview
repro.trackAddToWishlist({
  value: 5000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing",
  content_id: "1234"
});
```

```js-inapp
Repro.trackAddToWishlist({
  value: 5000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing",
  content_id: "1234"
});
```

```dart
await Repro.trackAddToWishlist({
  "value": 5000.0,
  "currency": "JPY",
  "content_name": "Slim Jeans",
  "content_category": "Clothing & Shoes > Mens > Clothing",
  "content_id": "1234"
});
```

#### 支払い開始

購入手続きの開始をトラックします。

**使用例**

- ユーザーが「購入手続きへ」ボタンをタップしたとき

**プロパティ**

- content_id
- content_name
- content_category
- value
- currency
- num_items

```objc
RPRInitiateCheckoutProperties *properties = [[RPRInitiateCheckoutProperties alloc] init];

properties.value = 8000.0;
properties.currency = @"JPY";
properties.contentName = @"Slim Jeans";
properties.contentCategory = @"Clothing & Shoes > Mens > Clothing";
properties.contentID = @"1234";
properties.numItems = 2;

[Repro trackInitiateCheckout:properties];
```

```swift
import Repro.RPREventProperties

...

let properties = RPRInitiateCheckoutProperties()

properties.value = 8000.0
properties.currency = "JPY"
properties.contentName = "Slim Jeans"
properties.contentCategory = "Clothing & Shoes > Mens > Clothing"
properties.contentID = "1234"
properties.numItems = 2

Repro.trackInitiateCheckoutEvent(properties: properties)
```

```java
import io.repro.android.tracking.InitiateCheckoutProperties;

...

InitiateCheckoutProperties properties = new InitiateCheckoutProperties();

properties.setValue(8000.0);
properties.setCurrency("JPY");
properties.setContentName("Slim Jeans");
properties.setContentCategory("Clothing & Shoes > Mens > Clothing");
properties.setContentId("1234");
properties.setNumItems(2);

Repro.trackInitiateCheckout(properties);
```

```kotlin
import io.repro.android.tracking.InitiateCheckoutProperties

...

val properties = InitiateCheckoutProperties()

properties.value = 8000.0
properties.currency = "JPY"
properties.contentName = "Slim Jeans"
properties.contentCategory = "Clothing & Shoes > Mens > Clothing"
properties.contentId = "1234"
properties.numItems = 2

Repro.trackInitiateCheckout(properties)
```

```cpp
#include "ReproCpp.h"

...

repro::InitiateCheckoutProperties properties;

properties.setContentId("1234");
properties.setContentName("Slim Jeans");
properties.setContentCategory("Clothing & Shoes > Mens > Clothing");
properties.setValue(5000.0);
properties.setCurrency("JPY");
properties.setNumItems(10);

ReproCpp::trackInitiateCheckout(&properties);
```

```csharp
InitiateCheckoutProperties properties = new InitiateCheckoutProperties();

properties.SetContentID("1234");
properties.SetContentName("Slim Jeans");
properties.SetContentCategory("Clothing & Shoes > Mens > Clothing");
properties.SetValue(5000.0);
properties.SetCurrency("JPY");
properties.SetNumItems(10);

Repro.TrackInitiateCheckout (properties);
```

```js-cordova
Repro.trackInitiateCheckout({
  value: 8000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing",
  content_id: "1234"
});
```

```js-react-native
Repro.trackInitiateCheckout({
  value: 8000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing",
  content_id: "1234"
});
```

```js-webview
repro.trackInitiateCheckout({
  value: 8000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing",
  content_id: "1234"
});
```

```js-inapp
Repro.trackInitiateCheckout({
  value: 8000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing",
  content_id: "1234"
});
```

```dart
await Repro.trackInitiateCheckout({
  "value": 8000.0,
  "currency": "JPY",
  "content_name": "Slim Jeans",
  "content_category": "Clothing & Shoes > Mens > Clothing",
  "content_id": "1234"
});
```

#### 支払い情報追加

支払い情報の入力操作をトラックします。

**使用例**

- ユーザーが「支払情報を保存」ボタンをタップしたとき

**プロパティ**

- content_id
- content_category
- value
- currency

```objc
RPRAddPaymentInfoProperties *properties = [[RPRAddPaymentInfoProperties alloc] init];

properties.value = 8000.0;
properties.currency = @"JPY";
properties.contentCategory = @"Clothing & Shoes > Mens > Clothing";
properties.contentID = @"1234";

[Repro trackAddPaymentInfo:properties];
```

```swift
import Repro.RPREventProperties

...

let properties = RPRAddPaymentInfoProperties()

properties.value = 8000.0
properties.currency = "JPY"
properties.contentCategory = "Clothing & Shoes > Mens > Clothing"
properties.contentID = "1234"

Repro.trackAddPaymentInfoEvent(properties: properties)
```

```java
import io.repro.android.tracking.AddPaymentInfoProperties;

...

AddPaymentInfoProperties properties = new AddPaymentInfoProperties();

properties.setValue(8000.0);
properties.setCurrency("JPY");
properties.setContentCategory("Clothing & Shoes > Mens > Clothing");
properties.setContentId("1234");

Repro.trackAddPaymentInfo(properties);
```

```kotlin
import io.repro.android.tracking.AddPaymentInfoProperties

...

val properties = AddPaymentInfoProperties()

properties.value = 8000.0
properties.currency = "JPY"
properties.contentCategory = "Clothing & Shoes > Mens > Clothing"
properties.contentId = "1234"

Repro.trackAddPaymentInfo(properties)
```

```cpp
#include "ReproCpp.h"

...

repro::AddPaymentInfoProperties properties;

properties.setContentId("1234");
properties.setContentCategory("Clothing & Shoes > Mens > Clothing");
properties.setValue(5000.0);
properties.setCurrency("JPY");

ReproCpp::trackAddPaymentInfo(&properties);
```

```csharp
AddPaymentInfoProperties properties = new AddPaymentInfoProperties();

properties.SetContentID("1234");
properties.SetContentCategory("Clothing & Shoes > Mens > Clothing");
properties.SetValue(5000.0);
properties.SetCurrency("JPY");

Repro.TrackAddPaymentInfo (properties);
```

```js-cordova
Repro.trackAddPaymentInfo({
  value: 8000.0,
  currency: "JPY",
  content_category: "Clothing & Shoes > Mens > Clothing",
  content_id: "1234"
});
```

```js-react-native
Repro.trackAddPaymentInfo({
  value: 8000.0,
  currency: "JPY",
  content_category: "Clothing & Shoes > Mens > Clothing",
  content_id: "1234"
});
```

```js-webview
repro.trackAddPaymentInfo({
  value: 8000.0,
  currency: "JPY",
  content_category: "Clothing & Shoes > Mens > Clothing",
  content_id: "1234"
});
```

```js-inapp
Repro.trackAddPaymentInfo({
  value: 8000.0,
  currency: "JPY",
  content_category: "Clothing & Shoes > Mens > Clothing",
  content_id: "1234"
});
```

```dart
await Repro.trackAddPaymentInfo({
  "value": 8000.0,
  "currency": "JPY",
  "content_category": "Clothing & Shoes > Mens > Clothing",
  "content_id": "1234"
});
```



#### 購入

購入操作をトラックします。

**使用例**

- ユーザーが「購入確定」ボタンをタップしたとき

**プロパティ**

- content_id (**必須**、メソッドの第1引数に指定)
- value (**必須**、メソッドの第2引数に指定)
- currency (**必須**、メソッドの第3引数に指定)
- content_name
- content_category
- num_items

```objc
RPRPurchaseProperties *properties = [[RPRPurchaseProperties alloc] init];

properties.contentName = @"Slim Jeans";
properties.contentCategory = @"Clothing & Shoes > Mens > Clothing";
properties.numItems = 2;

[Repro trackPurchase:@"1234" value:8000.0 currency:@"JPY" properties:properties];
```

```swift
import Repro.RPREventProperties

...

let properties = RPRPurchaseProperties()

properties.contentName = "Slim Jeans"
properties.contentCategory = "Clothing & Shoes > Mens > Clothing"
properties.numItems = 2;

Repro.trackPurchaseEvent(contentID: "1234", value: 8000.0, currency: "JPY", properties: properties)
```

```java
import io.repro.android.tracking.PurchaseProperties;

...

PurchaseProperties properties = new PurchaseProperties();

properties.setContentName("Slim Jeans");
properties.setContentCategory("Clothing & Shoes > Mens > Clothing");
properties.setNumItems(2);

Repro.trackPurchase("1234", 8000.0, "JPY", properties);
```

```kotlin
import io.repro.android.tracking.PurchaseProperties

...

val properties = PurchaseProperties()

properties.contentName = "Slim Jeans"
properties.contentCategory = "Clothing & Shoes > Mens > Clothing"
properties.numItems = 2

Repro.trackPurchase("1234", 8000.0, "JPY", properties)
```

```cpp
#include "ReproCpp.h"

...

repro::PurchaseProperties properties;

properties.setContentName("Slim Jeans");
properties.setContentCategory("Clothing & Shoes > Mens > Clothing");
properties.setNumItems(2);

ReproCpp::trackPurchase("1234", 5000.0, "JPY", &properties);
```

```csharp
PurchaseProperties properties = new PurchaseProperties();

properties.SetContentName ("Slim Jeans");
properties.SetContentCategory ("Clothing & Shoes > Mens > Clothing");
properties.SetNumItems (2);

Repro.TrackPurchase ("1234", 100.0, "JPY", properties);
```

```js-cordova
Repro.trackPurchase("1234", 8000.0, "JPY", {
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing",
  num_items: 2
});
```

```js-react-native
Repro.trackPurchase("1234", 8000.0, "JPY", {
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing",
  num_items: 2
});
```

```js-webview
repro.trackPurchase("1234", 8000.0, "JPY", {
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing",
  num_items: 2
});
```

```js-inapp
Repro.trackPurchase("1234", 8000.0, "JPY", {
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing",
  num_items: 2
});
```

```dart
await Repro.trackPurchase("1234", 8000.0, "JPY", {
  "content_name": "Slim Jeans",
  "content_category": "Clothing & Shoes > Mens > Clothing",
  "num_items": 2
});
```

#### シェア

ソーシャル・ネットワーク (Facebook, Twitterなど) へのシェアをトラックします。

**使用例**

- ユーザーが「商品をシェアする」ボタンをタップしたとき

**プロパティ**

- content_id
- content_name
- content_category
- serviceName

```objc
RPRShareProperties *properties = [[RPRShareProperties alloc] init];

properties.contentCategory = @"Clothing & Shoes > Mens > Clothing";
properties.contentName = @"Slim Jeans";
properties.contentID = @"1234";
properties.serviceName = @"twitter";

[Repro trackShare:properties];
```

```swift
import Repro.RPREventProperties

...

let properties = RPRShareProperties()

properties.contentCategory = "Clothing & Shoes > Mens > Clothing"
properties.contentName = "Slim Jeans"
properties.contentID = "1234"
properties.serviceName = "twitter"

Repro.trackShareEvent(properties: properties)
```

```java
import io.repro.android.tracking.ShareProperties;

...

ShareProperties properties = new ShareProperties();

properties.setContentCategory("Clothing & Shoes > Mens > Clothing");
properties.setContentName("Slim Jeans");
properties.setContentId("1234");
properties.setServiceName("twitter");

Repro.trackShare(properties);
```

```kotlin
import io.repro.android.tracking.ShareProperties

...

val properties = ShareProperties()

properties.contentCategory = "Clothing & Shoes > Mens > Clothing"
properties.contentName = "Slim Jeans"
properties.contentId = "1234"
properties.serviceName = "twitter"

Repro.trackShare(properties)
```

```cpp
#include "ReproCpp.h"

...

repro::ShareProperties properties;

properties.setContentId("1234");
properties.setContentName("Slim Jeans");
properties.setContentCategory("Clothing & Shoes > Mens > Clothing");
properties.setServiceName("twitter");

ReproCpp::trackShare(&properties);
```

```csharp
ShareProperties properties = new ShareProperties();

properties.SetContentID ("1234");
properties.SetContentName ("Slim Jeans");
properties.SetContentCategory ("Clothing & Shoes > Mens > Clothing");
properties.SetServiceName ("twitter");

Repro.TrackShare (properties);
```

```js-cordova
Repro.trackShare({
  content_category: "Clothing & Shoes > Mens > Clothing",
  content_name: "Slim Jeans",
  content_id: "1234",
  service_name: "twitter"
});
```

```js-react-native
Repro.trackShare({
  content_category: "Clothing & Shoes > Mens > Clothing",
  content_name: "Slim Jeans",
  content_id: "1234",
  service_name: "twitter"
});
```

```js-webview
repro.trackShare({
  content_category: "Clothing & Shoes > Mens > Clothing",
  content_name: "Slim Jeans",
  content_id: "1234",
  service_name: "twitter"
});
```

```js-inapp
Repro.trackShare({
  content_category: "Clothing & Shoes > Mens > Clothing",
  content_name: "Slim Jeans",
  content_id: "1234",
  service_name: "twitter"
});
```

```dart
await Repro.trackShare({
  "content_category": "Clothing & Shoes > Mens > Clothing",
  "content_name": "Slim Jeans",
  "content_id": "1234",
  "service_name": "twitter"
});
```

#### リード

アプリの試用開始をトラックします。インストール時にユーザー登録を必須としていないアプリでご利用ください。

**使用例**

- ユーザーが「試しに使ってみる」などのボタンをタップしたとき

**プロパティ**

- content_name
- content_category
- value
- currency

```objc
RPRLeadProperties *properties = [[RPRLeadProperties alloc] init];

properties.value = 8000.0;
properties.currency = @"JPY";
properties.contentName = @"Slim Jeans";
properties.contentCategory = @"Clothing & Shoes > Mens > Clothing";

[Repro trackLead:properties];
```

```swift
import Repro.RPREventProperties

...

let properties = RPRLeadProperties()

properties.value = 8000.0
properties.currency = "JPY"
properties.contentName = "Slim Jeans"
properties.contentCategory = "Clothing & Shoes > Mens > Clothing"

Repro.trackLeadEvent(properties: properties)
```

```java
import io.repro.android.tracking.LeadProperties;

...

LeadProperties properties = new LeadProperties();

properties.setValue(8000.0);
properties.setCurrency("JPY");
properties.setContentName("Slim Jeans");
properties.setContentCategory("Clothing & Shoes > Mens > Clothing");

Repro.trackLead(properties);
```

```kotlin
import io.repro.android.tracking.LeadProperties

...

val properties = LeadProperties()

properties.value = 8000.0
properties.currency = "JPY"
properties.contentName = "Slim Jeans"
properties.contentCategory = "Clothing & Shoes > Mens > Clothing"

Repro.trackLead(properties)
```

```cpp
#include "ReproCpp.h"

...

repro::LeadProperties properties;

properties.setContentName("Slim Jeans");
properties.setContentCategory("Clothing & Shoes > Mens > Clothing");
properties.setValue(5000.0);
properties.setCurrency("JPY");

ReproCpp::trackLead(&properties);
```

```csharp
LeadProperties properties = new LeadProperties();

properties.SetContentName ("Slim Jeans");
properties.SetContentCategory ("Clothing & Shoes > Mens > Clothing");
properties.SetValue (5000.0);
properties.SetCurrency ("JPY");

Repro.TrackLead (properties);
```

```js-cordova
Repro.trackLead({
  value: 8000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing"
});
```

```js-react-native
Repro.trackLead({
  value: 8000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing"
});
```

```js-webview
repro.trackLead({
  value: 8000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing"
});
```

```js-inapp
Repro.trackLead({
  value: 8000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing"
});
```

```dart
await Repro.trackLead({
  "value": 8000.0,
  "currency": "JPY",
  "content_name": "Slim Jeans",
  "content_category": "Clothing & Shoes > Mens > Clothing"
});
```

<!-- completeRegistration: -->

#### ユーザー登録

ユーザー登録の完了をトラックします。

**使用例**

- ユーザーが「ユーザー登録」をタップしたとき

**プロパティ**

- content_name
- value
- currency
- status

```objc
RPRCompleteRegistrationProperties *properties = [[RPRCompleteRegistrationProperties alloc] init];

properties.value = 8000.0;
properties.currency = @"JPY";
properties.contentName = @"Slim Jeans";
properties.status = @"completed";

[Repro trackCompleteRegistration:properties];
```

```swift
import Repro.RPREventProperties

...

let properties = RPRCompleteRegistrationProperties()

properties.value = 8000.0
properties.currency = "JPY"
properties.contentName = "Slim Jeans"
properties.status = "completed"

Repro.trackCompleteRegistrationEvent(properties: properties)
```

```java
import io.repro.android.tracking.CompleteRegistrationProperties;

...

CompleteRegistrationProperties properties = new CompleteRegistrationProperties();

properties.setValue(8000.0);
properties.setCurrency("JPY");
properties.setContentName("Slim Jeans");
properties.setStatus("completed");

Repro.trackCompleteRegistration(properties);
```

```kotlin
import io.repro.android.tracking.CompleteRegistrationProperties

...

val properties = CompleteRegistrationProperties()

properties.value = 8000.0
properties.currency = "JPY"
properties.contentName = "Slim Jeans"
properties.status = "completed"

Repro.trackCompleteRegistration(properties)
```

```cpp
#include "ReproCpp.h"

...

repro::CompleteRegistrationProperties properties;

properties.setContentName("Slim Jeans");
properties.setValue(5000.0);
properties.setCurrency("JPY");
properties.setStatus("completed");

ReproCpp::trackCompleteRegistration(&properties);
```

```csharp
CompleteRegistrationProperties properties = new CompleteRegistrationProperties();

properties.SetContentName ("Slim Jeans");
properties.SetValue (5000.0);
properties.SetCurrency ("JPY");
properties.SetStatus ("completed");

Repro.TrackCompleteRegistration (properties);
```

```js-cordova
Repro.trackCompleteRegistration({
  value: 8000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  status: "completed"
});
```

```js-react-native
Repro.trackCompleteRegistration({
  value: 8000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  status: "completed"
});
```

```js-webview
repro.trackCompleteRegistration({
  value: 8000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  status: "completed"
});
```

```js-inapp
Repro.trackCompleteRegistration({
  value: 8000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  status: "completed"
});
```

```dart
await Repro.trackCompleteRegistration({
  "value": 8000.0,
  "currency": "JPY",
  "content_name": "Slim Jeans",
  "status": "completed"
});
```



#### 独自プロパティの追加

標準イベントにはアプリケーション独自のプロパティを追加することもできます。 `extras` プロパティにディクショナリをセットしてください。

##### NOTE
ディクショナリのキーが標準イベントのプロパティ名と重複する場合、ディクショナリの値は無視されます。

```objc
RPRViewContentProperties *properties = [[RPRViewContentProperties alloc] init];

properties.value = 5000.0;
properties.currency = @"JPY";
properties.contentName = @"Slim Jeans";
properties.contentCategory = @"Clothing & Shoes > Mens > Clothing";
properties.extras = @{
                     @"color":@"blue",
                     @"waist":@80
                     };

[Repro trackViewContent:@"1234" properties:properties];
```

```swift
import Repro.RPREventProperties

...

let properties = RPRViewContentProperties()

properties.value = 5000.0
properties.currency = "JPY"
properties.contentName = "Slim Jeans"
properties.contentCategory = "Clothing & Shoes > Mens > Clothing"
properties.extras = [
                    "color": "blue",
                    "waist": 80
                    ]

Repro.trackViewContentEvent(contentID: "1234", properties: properties)
```

```java
import io.repro.android.tracking.ViewContentProperties;

...

ViewContentProperties properties = new ViewContentProperties();

properties.setValue(5000.0);
properties.setCurrency("JPY");
properties.setContentName("Slim Jeans");
properties.setContentCategory("Clothing & Shoes > Mens > Clothing");
properties.setExtras(new HashMap<String, Object>() {{
    put("color", "blue");
    put("waist", 80);
}});

Repro.trackViewContent("1234", properties);
```

```kotlin
import io.repro.android.tracking.ViewContentProperties

...

val properties = ViewContentProperties()

properties.value = 5000.0
properties.currency = "JPY"
properties.contentName = "Slim Jeans"
properties.contentCategory = "Clothing & Shoes > Mens > Clothing"
properties.extras = mapOf(
    "color" to "blue",
    "waist" to 80
    )

Repro.trackViewContent("1234", properties)
```

```cpp
#include "ReproCpp.h"

...

repro::ViewContentProperties properties;

properties.setContentName("Slim Jeans");
properties.setContentCategory("Clothing & Shoes > Mens > Clothing");
properties.setValue(5000.0);
properties.setCurrency("JPY");
properties.setExtras(R"({"color": "blue", "waist": 90})"); /* Raw string literals, same with "{\"color\": \"blue\", \"waist\": 90}" */

ReproCpp::trackViewContent("1234", &properties);
```

```csharp
ViewContentProperties properties = new ViewContentProperties();

properties.SetContentName ("Slim Jeans");
properties.SetContentCategory ("Clothing & Shoes > Mens > Clothing");
properties.SetValue (5000.0);
properties.SetCurrency ("JPY");

properties.SetExtras("{\"color\": \"blue\", \"waist\": 80}");

Repro.TrackViewContent ("1234", properties);
```

```js-cordova
Repro.trackViewContent("1234", {
  value: 5000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing",
  extras: {
    color: "blue",
    waist: 90
  }
});
```

```js-react-native
Repro.trackViewContent("1234", {
  value: 5000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing",
  extras: {
    color: "blue",
    waist: 90
  }
});
```

```js-webview
repro.trackViewContent("1234", {
  value: 5000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing",
  extras: {
    color: "blue",
    waist: 90
  }
});
```

```js-inapp
Repro.trackViewContent("1234", {
  value: 5000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing",
  extras: {
    color: "blue",
    waist: 90
  }
});
```

```dart
await Repro.trackViewContent("1234", {
  "value": 5000.0,
  "currency": "JPY",
  "content_name": "Slim Jeans",
  "content_category": "Clothing & Shoes > Mens > Clothing",
  "extras": {
    "color": "blue",
    "waist": 90
  }
});
```



### カスタムイベント

標準イベントとして定義されているもの以外の、アプリケーション独自のイベントをトラックします。

##### WARNING
- トラッキングしたイベントをアプリ内メッセージの配信トリガーに利用する場合、アプリの画面描画サイクルを鑑みた実装を行う必要があります。 [アプリ内メッセージ](https://docs.repro.io/ja/dev/sdk/in-app-message.md#in-app-message-show-timing) を参照し、実装タイミングを調節してください。
- アプリ内メッセージの配信トリガーとして利用できない場合でも、イベントをトラッキングし、計測することはできます。

##### NOTE
- `___repro___` から始まるイベント名は使用できません。
- イベント名にnullや空文字列は不可、上限は191文字です。

```objc
// Custom event
[Repro track:@"Finished tutorial" properties:nil];

// Custom event with properties
[Repro track:@"user review" properties:@{
    @"rating": @3
}];
```

```swift
// Custom event
Repro.track(event: "Finished tutorial", properties: [:])

// Custom event with properties
Repro.track(event: "user review", properties:[
    "rating": 3
])
```

```java
// Custom event
Repro.track("Finished tutorial");

// Custom event with properties
Repro.track("user review", new HashMap<String, Object>() {{
  put("rating", 3);
}});
```

```kotlin
// Custom event
Repro.track("Finished tutorial")

// Custom event with properties
Repro.track("user review", mapOf(
        "rating" to 3
    )
)
```

```cpp
// Custom event
ReproCpp::track("Finished tutorial");

// Event with properties
ReproCpp::trackWithProperties("user review", R"({ "rating": "3" })"); /* Raw string literals, same with {\"rating\": \"3\"} */
```

```csharp
// Custom event
Repro.Track ("Finished tutorial");

// Custom event with properties
Repro.TrackWithProperties ("user review", "{\"rating\": 3}");
```

```js-cordova
// Custom event
Repro.track("Finished tutorial");

// Custom event with properties
Repro.trackWithProperties("user review", "{\"rating\": \"3\"}");
```

```js-react-native
// Custom event
Repro.track("Finished tutorial", {});

// Custom event with properties
Repro.track("user review", { rating: 3 });
```

```js-webview
// Custom event
repro.track("Finished tutorial");

// Custom event with properties
repro.track("user review", { rating: 3 });
```

```js-inapp
// Custom event
Repro.track("Finished tutorial");

// Custom event with properties
Repro.track("user review", { rating: 3 });
```

```dart
// Custom event
await Repro.track("Finished tutorial");

// Custom event with properties
await Repro.track("user review", { "rating": 3 });
```

---

## アプリ内メッセージ

アプリ内メッセージはSDKをインストールするだけで利用できます。表示タイミングはメッセージ作成時に [メッセージ表示トリガー](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md#in-app-message-delivery) で指定してください。

ただし以下のケースに当てはまる場合、実装の追加／変更を行う必要があります。

### 実装の追加／変更が必要なケース

#### アプリ起動時にスプラッシュスクリーンを表示したり画面遷移をしている場合

アプリの実装がこのケースの場合、アプリ内メッセージの表示トリガーを「アプリ起動」にした際にメッセージがうまく表示されないことがあります。

この場合、以下の手順でSDK APIを利用して起動時のアプリ内メッセージの表示タイミングをずらすことが可能です。

##### ご利用中のSDKバージョンが5以上の場合

まず、 `disableInAppMessagesOnForegroundTransition` を `setup` より前に呼び出してください。

```objc
#import <Repro/Repro.h>

...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    ...
    [Repro disableInAppMessagesOnForegroundTransition];
    [Repro setup:@"YOUR_APP_TOKEN"];
    ...
}
```

```swift
import Repro

...

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    ...
    Repro.disableInAppMessagesOnForegroundTransition()
    Repro.setup(token: "YOUR_APP_TOKEN")
    ...
}
```

```java
import io.repro.android.Repro;
...

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        ...
        Repro.disableInAppMessagesOnForegroundTransition();
        Repro.setup(this, "YOUR_APP_TOKEN");
        ...
    }
}
```

```kotlin
import io.repro.android.Repro
...

class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        ...
        Repro.disableInAppMessagesOnForegroundTransition()
        Repro.setup(this, "YOUR_APP_TOKEN")
        ...
    }
}
```

```cpp
ReproCpp::disableInAppMessagesOnForegroundTransition();
```

```csharp
using UnityEngine;

public class MyBehaviour : MonoBehaviour {

    void Start () {
        ...
        Repro.DisableInAppMessagesOnForegroundTransition()
        Repro.Setup ("YOUR_APP_TOKEN");
        ...
    }
}
```

```js-cordova
onDeviceReady: function() {
    app.receivedEvent('deviceready');
    Repro.disableInAppMessagesOnForegroundTransition();
    Repro.setup("YOUR_APP_TOKEN");
}
```

```js-react-native
//
// call disableInAppMessageOnActive method in your native code like shown bellow.
//

// iOS(Objective-C): AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [Repro disableInAppMessagesOnForegroundTransition];
    [Repro setup:@"YOUR_APP_TOKEN"];
    ...
}

// Android(Java): MainApplication
@Override
public void onCreate() {
    super.onCreate();
    Repro.disableInAppMessagesOnForegroundTransition()
    Repro.setup(this, "YOUR_APP_TOKEN");
    ...
}
```

```dart
//
// call disableInAppMessagesOnForegroundTransition method in your native code like shown bellow.
//

// iOS(Objective-C): AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    ...
    [Repro disableInAppMessagesOnForegroundTransition];
    [Repro setup:@"YOUR_APP_TOKEN"];
    ...
}

// Android(Java): MyApplication
@Override
public void onCreate() {
    super.onCreate();
    Repro.disableInAppMessagesOnForegroundTransition();
    Repro.setup(this, "YOUR_APP_TOKEN");
    ...
}
```

さらに、スプラッシュスクリーンの表示が終わったタイミングで `enableInAppMessagesOnForegroundTransition` を呼び出してください。

```objc
[Repro enableInAppMessagesOnForegroundTransition];
```

```swift
Repro.enableInAppMessagesOnForegroundTransition()
```

```java
import io.repro.android.Repro;

public class MyActivity extends Activity {

    protected void someFunc() {
      ...

      // you should pass current visible activity to enableInAppMessagesOnForegroundTransition()
      //Repro.enableInAppMessagesOnForegroundTransition(this);
      // activity not necessary for Android SDK 5.24.0 Later
      Repro.enableInAppMessagesOnForegroundTransition();

      ...
    }
}
```

```kotlin
import io.repro.android.Repro

class MyActivity : Activity() {

    protected fun someFunc() {
        ...

        // you should pass current visible activity to enableInAppMessagesOnForegroundTransition()
        //Repro.enableInAppMessagesOnForegroundTransition(this)
        // activity not necessary for Android SDK 5.24.0 Later
        Repro.enableInAppMessagesOnForegroundTransition()

        ...
    }
}
```

```cpp
ReproCpp::enableInAppMessagesOnForegroundTransition();
```

```csharp
Repro.EnableInAppMessagesOnForegroundTransition();
```

```js-cordova
Repro.enableInAppMessagesOnForegroundTransition();
```

```js-react-native
Repro.enableInAppMessagesOnForegroundTransition();
```

```dart
await Repro.enableInAppMessagesOnForegroundTransition();
```

##### NOTE
disableInAppMessagesOnForegroundTransition は、アプリ起動時にスプラッシュスクリーンを採用している場合に活用することを想定した「アプリ起動」イベント専用のメソッドです。
「アプリ起動」以外のイベントが表示トリガーであるメッセージを表示するタイミングの制御をすることはできません。

##### WARNING
Android SDK 5.24.0 より `enableInAppMessagesOnForegroundTransition` は、引数の `Activity` が不要になりました。引数ありの `enableInAppMessagesOnForegroundTransition` はそのまま使用可能ですが、 `Deprecated` となります。引数なしの `enableInAppMessagesOnForegroundTransition` をご利用ください。

##### ご利用中のSDKバージョンが5未満の場合

まず、 `disableInAppMessageOnActive` を `setup` より前に呼び出してください。

```objc
#import <Repro/Repro.h>

...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    ...
    [Repro disableInAppMessageOnActive];
    [Repro setup:@"YOUR_APP_TOKEN"];
    ...
}
```

```swift
import Repro

...

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    ...
    Repro.disableInAppMessageOnActive()
    Repro.setup(token: "YOUR_APP_TOKEN")
    ...
}
```

```java
import io.repro.android.Repro;
...

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        ...
        Repro.disableInAppMessageOnActive();
        Repro.setup(this, "YOUR_APP_TOKEN");
        ...
    }
}
```

```kotlin
import io.repro.android.Repro
...

class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        ...
        Repro.disableInAppMessageOnActive()
        Repro.setup(this, "YOUR_APP_TOKEN")
        ...
    }
}
```

```cpp
#include "ReproCpp.h"

bool AppDelegate::applicationDidFinishLaunching() {
    ...
    ReproCpp::disableInAppMessageOnActive();
    ReproCpp::setup("YOUR_APP_TOKEN");
    ...
}
```

```csharp
using UnityEngine;

public class MyBehaviour : MonoBehaviour {

    void Start () {
        Repro.DisableInAppMessageOnActive ();
        Repro.Setup ("YOUR_APP_TOKEN");
    }
}
```

```js-cordova
onDeviceReady: function() {
    app.receivedEvent('deviceready');
    Repro.disableInAppMessageOnActive();
    Repro.setup("YOUR_APP_TOKEN");
}
```

```js-react-native
//
// call disableInAppMessageOnActive method in your native code like shown bellow.
//

// iOS(Objective-C): AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [Repro disableInAppMessageOnActive];
    [Repro setup:@"YOUR_APP_TOKEN"];
    ...
}

// Android(Java): MainApplication
@Override
public void onCreate() {
    super.onCreate();
    Repro.disableInAppMessageOnActive()
    Repro.setup(this, "YOUR_APP_TOKEN");
    ...
}
```

```dart
// Flutter SDK does not support this feature under SDK version 5.
```

さらに、メッセージを表示しても問題ないタイミングで `showInAppMessage` を呼び出してください。

```objc
[Repro showInAppMessage];
```

```swift
Repro.showInAppMessage()
```

```java
import io.repro.android.Repro;

public class MyActivity extends Activity {

    protected void someFunc() {
      ...

      // you should pass current visible activity to showInAppMessage()
      Repro.showInAppMessage(this);

      ...
    }
}
```

```kotlin
import io.repro.android.Repro

class MyActivity : Activity() {

    protected fun someFunc() {
        ...

        // you should pass current visible activity to showInAppMessage()
        Repro.showInAppMessage(this)

        ...
    }
}
```

```cpp
ReproCpp::showInAppMessage();
```

```csharp
Repro.ShowInAppMessage ();
```

```js-cordova
Repro.showInAppMessage();
```

```js-react-native
Repro.showInAppMessage();
```

```dart
// Flutter SDK does not support this feature under SDK version 5.
```

##### NOTE
disableInAppMessageOnActive は、アプリ起動時にスプラッシュスクリーンを採用している場合に活用することを想定した「アプリ起動」イベント専用のメソッドです。
「アプリ起動」以外のイベントが表示トリガーであるメッセージを表示するタイミングの制御をすることはできません。

#### アプリ起動直後に実行されるイベント（「アプリ起動」以外）をアプリ内メッセージの表示トリガーに利用する場合

SDKはアプリフォアグラウンド後に表示すべきアプリ内メッセージの情報をサーバから取得します。
このためアプリ起動直後（例えばAndroidの場合、1つ目のActivityのonResumeなど）では情報取得が完了しておらず、メッセージが表示されない可能性があります。

この場合は、アプリ内メッセージの表示トリガーを「アプリ起動」に変更するか、当該イベントの実行を遅延させるなどをご検討ください。



#### 画面遷移前後に実行されるイベントをアプリ内メッセージの表示トリガーに利用する場合

画面遷移前後にアプリ内メッセージを表示しようとすると、描画タイミングの影響によりメッセージが表示されない可能性があります。

以下の表を参考に、アプリ内メッセージの表示トリガーに利用するイベントの実装箇所を見直しください。

**iOS**

| 実行タイミング | ダイアログ、オーバーレイ | バナー |
| --- | --- | --- |
| viewDidLoad | × | × |
| viewWillAppear | ◯ | ◯ |
| viewDidAppear | ○ | ◯ |
| viewWillDisappear | ◯ | ◯ |
| viewDidDisappear | ○ | × |

**Android**

| 実行タイミング | ダイアログ、オーバーレイ | バナー |
| --- | --- | --- |
| onCreate | × | × |
| onStart | × | × |
| onResume | ○ | ◯ |
| onPause | × | × |
| onStop | ○ | ◯ |
| onDestroy | ○ | ◯ |
| onRestart | × | × |

##### WARNING
Androidはアプリ内メッセージを表示する時点でresumeの状態であるActivityがなければメッセージを表示できません。

#### カスタムURL Schemeを使用する場合

カスタムURL Schemeのスキーム部分は小文字で指定してください。
HTMLアプリ内メッセージで表示したボタンにカスタムURL Schemeを使用して遷移するときに、スキーム部分が自動的に小文字に変換されて処理されます。
変換された結果、スキームが一致しない問題が発生する可能性がありますのでご注意ください。

#### ユニバーサルリンク/アプリリンクを使用する場合



端末に表示されたプッシュ通知およびアプリ内メッセージに設定されたリンクをタップした際に実行されるURLには、ユニバーサルリンク（またはアプリリンクと呼ばれる）を指定することが可能です。
（簡単のため、以下ではこれらをユニバーサルリンクと呼びます）

アプリにてユニバーサルリンクの実行時の処理を追加するには、以下の通り実装を行う必要があります。
（ここで設定された動作は、プッシュ通知およびアプリ内メッセージ対し有効となります。）

##### ユニバーサルリンクのURLパターンを登録する

ユニバーサルリンクを利用するためには、まずユニバーサルリンクのURLのパターン（正規表現）を指定する必要があります。

##### NOTE
パターン（正規表現）に合致すると、プッシュ通知の開封時や、アプリ内メッセージの遷移先に設定されたURLに対して、後述のコールバック処理をキックします。

また、アプリ内メッセージでHTMLコンテンツを表示するとき、そのコンテンツ内で発生したリクエストに対してもユニバーサルリンクの判定が行われます。

この指定は、iOSの場合は `AppDelegate` または `.plist` ファイル、Androidの場合は `Application` 継承クラス または `AndroidManifest.xml` ファイルのどちらか一方に記述することで行うことができます。

```objc
// AppDelegate.m

#import <Repro/Repro.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [Repro addOpenUrlFilterRegEx:@"https://example\\.com/page/"];
    [Repro addOpenUrlFilterRegEx:@"your-domain\\.com/.+\?universal=true"];
    ...
}


// .plist file
/*
<dict>
    <key>RPROpenUrlFilterRegExList</key>
    <array>
        <string>https://example\.com/page/</string>
        <string>your-domain\.com/.+\?universal=true</string>
    </array>
    ...
</dict>
*/
```

```java
// MyApplication.java

import io.repro.android.Repro;

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        Repro.addOpenUrlFilterRegEx("https://example\\.com/page/");
        Repro.addOpenUrlFilterRegEx("your-domain\\.com/.+\\?universal=true");
        ...
    }
...
}


// AndroidManifest.xml
// To specify multiple URL patterns, enter them separated by commas.
<application>
    ...
    <meta-data
        android:name="io.repro.android.OpenUrlFilterRegExList"
        android:value="https://example\\.com/page/;your-domain\\.com/.+\\?universal=true">
    </meta-data>
</application>
```

```kotlin
// MyApplication.kt

import io.repro.android.Repro

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        Repro.addOpenUrlFilterRegEx("https://example\\.com/page/")
        Repro.addOpenUrlFilterRegEx("your-domain\\.com/.+\\?universal=true")
        ...
    }
    ...
}


// AndroidManifest.xml
// To specify multiple URL patterns, enter them separated by commas.
<application>
    ...
    <meta-data
        android:name="io.repro.android.OpenUrlFilterRegExList"
        android:value="https://example\\.com/page/;your-domain\\.com/.+\\?universal=true">
    </meta-data>
</application>
```

```swift
// AppDelegate.swift

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
{
    Repro.add(openUrlFilterRegEx: "https://example\\.com/page/")
    Repro.add(openUrlFilterRegEx: "your-domain\\.com/.+\\?universal=true")
    ...
}

// .plist file
/*
<dict>
    <key>RPROpenUrlFilterRegExList</key>
    <array>
        <string>https://example\.com/page/</string>
        <string>your-domain\.com/.+\?universal=true</string>
    </array>
    ...
</dict>
*/
```

```dart
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

```csharp
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

```cpp
// YourAppNameScene.cpp

bool YourAppName::init() {
    ReproCpp::addOpenUrlFilterRegEx("https://example\\.com/page/");
    ReproCpp::addOpenUrlFilterRegEx("your-domain\\.com/.+\\?universal=true");
    ...
}
```

```js-cordova
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

```js-react-native
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

##### WARNING
ユニバーサルリンクとして設定するURLパターンは、可能な限り **ドメインとパスまで含めて具体的に指定** し、 **全て小文字で指定** してください。

もし、 https のようにスキームのみを指定した場合、アプリ内メッセージで表示された画面内で実行されたスクリプトなどによるリクエストもユニバーサルリンクと誤って判定され、意図しないタイミングでコールバック処理が実行される可能性があります。

また、URLパターンのスキーム/ドメイン部分に大文字を使用した場合、HTMLアプリ内メッセージで表示したボタンからユニバーサルリンクを使って遷移させようとするときに、スキーム/ドメイン部分が自動的に小文字に変換されて処理されます。パターン（正規表現）に一致せず、意図したタイミングでコールバック処理が実行されない可能性があります。

##### ユニバーサルリンク実行時の処理を登録する

次に、ユニバーサルリンクが実行された際に動作するコールバック処理を実装します。
処理内には、例えばURLのパターンに応じて画面遷移を行う動作などを記述します。

```objc
#import <Repro/Repro.h>

...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [Repro setOpenUrlCallback:^(NSURL *url) {
        if ([url.host isEqualToString:@"example.com"]) {
            // In case of your universal link perform navigation, present content, ...
            handleUniversalLink(url);
        }
    }];

    ...
    [Repro setup:@"YOUR_APP_TOKEN"];
    ...
}
```

```swift
// Set a callback that is executed everytime an URL is about to be opened
Repro.setOpenUrlCallback { url in
    if url.host == "example.com" {
        // In case of your universal link perform navigation, present content, ...
        handleUniversalLink(url)
    }
}
...
Repro.setup(token: "YOUR_APP_TOKEN")
...
```

```java
import io.repro.android.Repro;

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        // In order to execute a callback when a push notification is tapped,
        // the callback must be set in Application, not Activity.
        Repro.setOpenUrlCallback(new Repro.OpenUrlCallback() {
            // ** This callback method is executed in the main thread **
            @Override
            public void onOpened(Uri uri) {
                if ("example.com".equals(uri.getHost())) {
                    // In case of your universal link perform navigation, present content, ...
                }
            }
        });

        ...
        Repro.setup(this, YOUR_APP_TOKEN);
        ...
    }
    ...
}
```

```kotlin
import io.repro.android.Repro

class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        // In order to execute a callback when a push notification is tapped,
        // the callback must be set in Application, not Activity.
        Repro.setOpenUrlCallback { uri ->
            // ** This callback method is executed in the main thread **
            if (uri.host == "example.com") {
                // In case of your universal link perform navigation, present content, ...
            }
        }

        ...
        Repro.setup(this, "YOUR_APP_TOKEN")
        ...
    }
    ...
}
```

```dart
Repro.setOpenUrlCallback((uri) { // uri is of type Uri
   debugPrint("Universal Link Callback Handler received: " + uri.toString());
});
```

```csharp
// Somewhere before Repro.Setup(...)
Repro.SetOpenUrlCallback(uri => // uri is of type Uri
{
    Debug.Log("Universal Link Callback Handler received: " + uri.ToString());
});
```

```cpp
bool YourAppName::init() {
    ReproCpp::addOpenUrlFilterRegEx(...);

    ReproCpp::setOpenUrlCallback([](const char *url) {
        if (strcmp(url, "example.com") == 0) {
            // In case of your universal link perform navigation, present content, ...
        }
    });

    ReproCpp::setup("YOUR_APP_TOKEN")
    ...
}
```

```js-cordova
Repro.setOpenUrlCallback(function(url) { // url is of type String
    alert('Universal Link Callback Handler received: ' + url);
    if (url.includes("http://example.org")) {
        // In case of your universal link perform navigation, present content, ...
    }
});
```

```js-react-native
Repro.setOpenUrlCallback( (url) => {  // url is of type String
    console.log('Universal Link Callback Handler received: ' + url);
    if (url.includes("http://example.org")) {
        // In case of your universal link perform navigation, present content, ...
    }
});
```

##### NOTE
Cocos2d-xをご利用の場合のみ、別途ブリッジ処理の実装が必要です。
実装方法の詳細は [ブリッジクラスの追加](https://docs.repro.io/ja/dev/sdk/getstarted/cocos2d-x.md#cocos2d-x-add-bridge-class) を参照してください。



#### App-Bound Domains を有効にしている場合（iOSのみ）

iOS の [App-Bound Domains](https://webkit.org/blog/10882/app-bound-domains/) を有効にしている場合、そのままでは [HTMLアプリ内メッセージ](https://docs.repro.io/ja/dashboard/campaign/html-in-app-message.md) が表示されません。

[HTMLアプリ内メッセージ](https://docs.repro.io/ja/dashboard/campaign/html-in-app-message.md) を表示するためには、以下の対応を行う必要があります。

- iOS SDKバージョン5.22.0以上にアップデートしてください
- App-Bound Domains のリストに https://io.repro.repro を追加するか、アプリの `Info.plist` ファイルに `RPRHtmlInAppBaseUrl` を追加し、 App-Bound Domains で利用中のURLを指定してください

以下はアプリの `Info.plist` ファイルに `RPRHtmlInAppBaseUrl` を追加するサンプルコードです。

```xml
<dict>
    ...
    <key>RPRHtmlInAppBaseUrl</key>
    <string>https://example.com</string>
</dict>
```

---

## アプリ内メッセージ

アプリ内メッセージは、アプリを使用中の特定のユーザーに対し、適切なタイミングで、画像やボタンのついたカスタマイズ可能なダイアログメッセージをポップアップで表示できる機能です。管理画面でメッセージを登録するだけで、ソースコードを変更することなく、既にリリースされたアプリにメッセージを配信することができるので、開発者の手を借りずに、マーケターだけでコンバージョンを上げるためのキャンペーンを配信することができます。



以下の設定をカスタマイズすることで、エンドユーザーの行動に即した効果的なマーケティング施策を実行することができます。

- 画像
- ブラウザでWebサイトを開くためのURLやアプリ内の任意の画面に遷移するためのディープリンクを埋め込めるボタン
- スケジュール
- 配信対象となるユーザー
- メッセージ表示タイミング

例えば:

- カートに商品を入れたあと購入に至らなかったユーザーに対しクーポンを配信する
- コンバージョンをあげるために、数日前に登録したユーザーに適切なナビゲーションを表示する

アプリ内メッセージはプッシュ通知とは異なり、通知を非許可にしているユーザーにもメッセージを送ることができます。

また、作成されたアプリ内メッセージは、アクションボタンかもしくはメッセージ上部のバツボタンのいずれかを押下した時に「表示された」と判断します。

### アプリ内メッセージを作成する

管理画面を開いて以下を実行してください。

**マーケティング > メッセージ** に行き、 **新規作成 > アプリ内メッセージ** をクリックしてください。



#### メッセージテンプレートを選択する

メッセージを新たに作成する際に、テンプレート選択画面が表示されます。選択画面に並んだテンプレートの中から、表示させたいメッセージの構成を決定します。
アプリ内メッセージで利用できるテンプレートは大きく以下 2 種類が存在します。

- **組み込み(Native)テンプレート**: テンプレート毎に決められた入力項目を穴埋めし、メッセージを作成・配信することができます。
- **HTML(WebView)テンプレート**: HTML や CSS を用いてメッセージをカスタマイズすることで、組み込み(Native)テンプレートでは表現できないアプリ内メッセージの作成・配信が可能です。詳細は [こちら](https://docs.repro.io/ja/dashboard/campaign/html-in-app-message.md) をご覧ください。

また、表示させたいメッセージの構成ごとにテンプレートが用意されています。それぞれのテンプレートで、ボタンやテキスト、画像の有無が指定されています。

- テキスト: 配信するメッセージに見出しと本文を設置できます
- 画像: 配信するメッセージに画像を添付できます
- ボタン: エンドユーザーがタップするボタンを配置できます。ボタンをタップした際に任意の [イベント](https://docs.repro.io/ja/dev/sdk/tracking.md) をトラッキングすることができます





#### キャンペーン設定



##### キャンペーン名

キャンペーン名を設定します。アプリ内メッセージの一覧に表示されます。

##### コンバージョンイベントを指定

キャンペーンのゴールとなるイベントを指定します。アプリ内メッセージを受信してから24時間以内にこのイベントを実施したユーザーの数が集計されます。詳細は [こちら](#inapp-measurement) をご覧ください。



###### キャンペーンをニュースフィードとして利用するかを指定

上記の画像にある「通知をニュースフィードとして使う」のチェックボックスを使い、キャンペーンをニュースフィードとして利用するかを指定します。

ニュースフィードとは、**ユーザーごとのキャンペーンの配信履歴** のことです。この履歴を利用することで、今までに送ったキャンペーンの履歴をアプリ内のお知らせ欄で表示するといったことが可能です。

ご利用に際しては、アプリ側で実装が必要になります。詳細は [開発ガイド](https://docs.repro.io/ja/dev/sdk/newsfeed.md) をご覧ください。

##### WARNING
アプリ内メッセージおよびWebメッセージをニュースフィードとして利用する際には、仕様上下記のようなユースケースでは意図した挙動とならないことがございますのでご注意ください。

例) 購入イベントをトリガーにして、作成されたキャンペーンをニュースフィードとして利用する場合

- ニュースフィードはキャンペーンとは別に独立して作成されるため、キャンペーンが表示されていなくてもニュースフィードとしては取得が可能になります。



### コンテンツを作成する

選択したテンプレートをもとに、配信するメッセージのコンテンツを作成します。編集可能なコンテンツはテンプレートにより異なります。以下ではテンプレートに編集できるコンテンツについて説明します。

##### NOTE
「変数の挿入」ボタンがある項目には、Liquid記法によってユーザープロフィールの値を挿入することができます。詳細は [Liquidによるパーソナライズ](https://docs.repro.io/ja/dashboard/campaign/liquid-personalization.md) をご覧ください。

#### ダイアログ(テキスト + ボタン)

メッセージのコンテンツとしてテキストとボタンを表示することができます。ボタンは１つまたは２つ表示でき、指定のページを開くURLを設定することができます。

下記のフォームに入力してアプリ内メッセージを作成します。



**背景色**
: メッセージが表示される外側の領域の背景色と、ダイアログ部分の背景色を個別に指定します。

**見出し** (任意)
: メッセージのヘッダーを指定します。テキストの色を指定できます。

**本文**
: メッセージの本文を指定します。テキストの色を指定できます。

**アクションボタン**
: アクションボタンに表示するテキストを指定します。ボタンの背景色とテキストの色を指定できます。

**ディープリンクもしくはURL (任意)**
: URLを指定するとボタンを押した時に指定したURLのページを開くことができます。URLを指定しないでボタンを押した場合はただアプリ内メッセージが閉じます。
   
  - 文字列長
    - 最大: 1000文字
   
  ディープリンクは以下3種類のディープリンクに対応しています。
   
  - ユニバーサルリンク
  - アプリリンク
  - カスタムURL Scheme
   
  ユニバーサルリンクとアプリリンクを指定したい場合は、 [ディープリンクに、ユニバーサルリンク（iOS）やアプリリンク（Android）を利用する場合](https://docs.repro.io/ja/dashboard/campaign/push-notification.md#clear-badge-setting) をご確認ください。

#### ダイアログ(画像)



ダイアログタイプの画像のみのアプリ内メッセージでは、画像だけを表示することができます。

下記のフォームに入力してアプリ内メッセージを作成します。



##### NOTE
選択した画像ファイルが大きい場合は、メッセージが表示されるまでに時間がかかる場合があります。
300KB 以内の画像ファイルを使用することを推奨します。

**背景色**
: メッセージが表示される外側の領域の背景色を指定します。

**画像**
: メッセージに表示する画像を指定します。
   
  - ファイルフォーマット: JPEG、PNG
  - ファイルサイズ
    - 最大: 1MB
    - 推奨: 300KB 以下
  - 画像サイズ
    - 最大: 3000px × 3000px
    - 推奨: 1152px × 1500px（縦向き）、1500px × 1152px（横向き）

**ディープリンクもしくはURL (任意)**
: URLを指定すると画像を押した時に指定したURLのページを開くことができます。URLを指定しないで画像を押した場合はただアプリ内メッセージが閉じます。
   
  - 文字列長
    - 最大: 1000文字
   
  ディープリンクは以下3種類のディープリンクに対応しています。
   
  - ユニバーサルリンク
  - アプリリンク
  - カスタムURL Scheme
   
  ユニバーサルリンクとアプリリンクを指定したい場合は、 [ディープリンクに、ユニバーサルリンク（iOS）やアプリリンク（Android）を利用する場合](https://docs.repro.io/ja/dashboard/campaign/push-notification.md#clear-badge-setting) をご確認ください。

**トラッキングイベント名 (任意)**
: トラッキングイベント名を指定すると画像をクリックしたときに計測されるイベントを変更することができます。

#### ダイアログ(テキスト + 画像 + ボタン)

メッセージのコンテンツとして画像、テキスト、ボタンを表示することができます。ボタンは１つまたは２つ表示でき、指定のページを開くURLを設定することもできます。

下記のフォームに入力してアプリ内メッセージを作成します。



##### NOTE
選択した画像ファイルが大きい場合は、メッセージが表示されるまでに時間がかかる場合があります。
300KB 以内の画像ファイルを使用することを推奨します。

**背景色**
: メッセージが表示される外側の領域の背景色と、ダイアログ部分の背景色を個別に指定します。

**画像**
: メッセージに表示する画像を指定します。
   
  - ファイルフォーマット: JPEG、PNG
  - ファイルサイズ
    - 最大: 1MB
    - 推奨: 300KB 以下
  - 画像サイズ
    - 最大: 3000px × 3000px
    - 推奨: 1152px × 1152px（縦向き）、960px × 960px（横向き）

**見出し (任意)**
: メッセージのヘッダーを指定します。テキストの色を指定できます。

**本文**
: メッセージの本文を指定します。テキストの色を指定できます。

**アクションボタン**
: アクションボタンに表示するテキストを指定します。ボタンの背景色とテキストの色を指定できます。

**ディープリンクもしくはURL (任意)**
: URLを指定するとボタンを押した時に指定したURLのページを開くことができます。URLを指定しないでボタンを押した場合はただアプリ内メッセージが閉じます。
   
  - 文字列長
    - 最大: 1000文字
   
  ディープリンクは以下3種類のディープリンクに対応しています。
   
  - ユニバーサルリンク
  - アプリリンク
  - カスタムURL Scheme
   
  ユニバーサルリンクとアプリリンクを指定したい場合は、 [ディープリンクに、ユニバーサルリンク（iOS）やアプリリンク（Android）を利用する場合](https://docs.repro.io/ja/dashboard/campaign/push-notification.md#clear-badge-setting) をご確認ください。

**トラッキングイベント名 (任意)**
: トラッキングイベント名を指定すると、アクションボタンをクリックしたときに計測されるイベントを変更することができます。

#### オーバーレイ(テキスト + 画像 + ボタン)

アプリの全画面を覆い被さるようなアプリ内メッセージを作成します。メッセージのコンテンツとして、画像、テキスト、ボタンを表示することができます。ボタンは１つ、または２つ表示でき、指定のページを開くURLを設定することもできます。

下記のフォームに入力してアプリ内メッセージを作成します。



##### NOTE
選択した画像ファイルが大きい場合は、メッセージが表示されるまでに時間がかかる場合があります。
300KB 以内の画像ファイルを使用することを推奨します。

**背景色**
: メッセージが表示される外側の領域の背景色を指定します。

**画像**
: メッセージに表示する画像を指定します。
   
  - ファイルフォーマット: JPEG、PNG
  - ファイルサイズ
    - 最大: 1MB
    - 推奨: 300KB 以下
  - 画像サイズ
    - 最大: 3000px × 3000px
    - 推奨: 1200px × 1200px（縦向き）、832px × 832px（横向き）

**見出し**
: メッセージのヘッダーを指定します。テキストの色を指定できます。

**本文**
: メッセージの本文を指定します。テキストの色を指定できます。

**アクションボタン**
: アクションボタンに表示するテキストを指定します。ボタンの背景色とテキストの色が指定できます。

**ディープリンクもしくはURL (任意)**
: URLを指定するとボタンを押した時に指定したURLのページを開くことができます。URLを指定しないでボタンを押した場合はただアプリ内メッセージが閉じます。
   
  - 文字列長
    - 最大: 1000文字
   
  ディープリンクは以下3種類のディープリンクに対応しています。
   
  - ユニバーサルリンク
  - アプリリンク
  - カスタムURL Scheme
   
  ユニバーサルリンクとアプリリンクを指定したい場合は、 [ディープリンクに、ユニバーサルリンク（iOS）やアプリリンク（Android）を利用する場合](https://docs.repro.io/ja/dashboard/campaign/push-notification.md#clear-badge-setting) をご確認ください。

**トラッキングイベント名 (任意)**
: トラッキングイベント名を指定すると、アクションボタンをクリックしたときに計測されるイベントを変更することができます。

#### バナー(テキスト + 画像)

バナータイプのアプリ内メッセージでは、メッセージのコンテンツとして画像とテキストをバナー内に表示することができます。バナーに指定のページを開くURLを設定することもできます。

下記のフォームに入力してアプリ内メッセージを作成します。



##### NOTE
選択した画像ファイルが大きい場合は、メッセージが表示されるまでに時間がかかる場合があります。
300KB 以内の画像ファイルを使用することを推奨します。

**背景色**
: メッセージが表示される外側の領域の背景色を指定します。

**画像**
: メッセージに表示する画像を指定します。
   
  - ファイルフォーマット: JPEG、PNG
  - ファイルサイズ
    - 最大: 1MB
    - 推奨: 300KB 以下
  - 画像サイズ
    - 最大: 3000px × 3000px
    - 推奨: 240px × 240px

**本文**
: メッセージの本文を指定します。テキストの色を指定できます。

**ディープリンクもしくはURL (任意)**
: URLを指定するとバナーを押した時に指定したURLのページを開くことができます。
   
  - 文字列長
    - 最大: 1000文字
   
  ディープリンクは以下3種類のディープリンクに対応しています。
   
  - ユニバーサルリンク
  - アプリリンク
  - カスタムURL Scheme
   
  ユニバーサルリンクとアプリリンクを指定したい場合は、 [ディープリンクに、ユニバーサルリンク（iOS）やアプリリンク（Android）を利用する場合](https://docs.repro.io/ja/dashboard/campaign/push-notification.md#clear-badge-setting) をご確認ください。

**トラッキングイベント名 (任意)**
: トラッキングイベント名を指定するとアクションボタンをクリックしたときに計測されるイベントを変更することができます。

#### 動画埋め込み(YouTube + テキスト + ボタン)

YouTubeの動画をメッセージ内に埋め込むことができます。ボタンは２つ表示でき、指定のページを開くURLを設定することもできます。

##### WARNING
- （重要） 2025年7月のYouTubeの仕様変更により、このテンプレートを利用した際に動画が再生されない事象が確認されています。Reproでは iOS SDK 5.21.1 以降 および Android SDK 5.20.3 以降で動作保証を行っていますが、今後の仕様次第で動作が変動する可能性があります。そのため、本テンプレートをご利用される際は必ずお客さまのアプリ環境で動画再生の可否をご確認のうえご利用ください。
- Unityを使ってビルドされたAndroidアプリでは、YouTubeの動画を埋め込んだメッセージが配信されますが動画が再生されません。ご注意ください。

##### NOTE
- このテンプレートの利用には、Repro iOS SDK 5.2.0 以上かつ iOS 9 以上、もしくはRepro Android SDK 5.1.0 以上かつ Android 5 以上が必要です。対象未満のバージョンには、メッセージは配信されません。
- メッセージ上の動画再生は、iOS SDK 5.21.1 以降 および Android SDK 5.20.3 以降で動作保証を行っています。
- 動画の公開が終了している・もしくは埋め込み不可に設定されているなどの理由で、配信されたメッセージ内の動画が再生されない場合があります。特にメッセージの配信期間を長期間に設定する場合は動画が再生可能な状態であることを定期的に確認するようにしてください。

下記のフォームに入力してアプリ内メッセージを作成します。



**背景色**
: メッセージが表示される外側の領域の背景色を指定します。

**YouTube URL**
: メッセージに表示するYouTubeのURLを指定します。指定するURLは、埋め込み用のURLを入力してください。以下キャプチャはYouTubeの再生画面より **共有 > 埋め込む** より、埋め込み用URLを取得した場合です。
   
  - 文字列長
    - 最大: 2000文字



##### NOTE
- YouTube URLには `playsinline=1` がデフォルトで付与されます。そのため、フォームから `playsinline` のパラメータが付与された場合、メッセージの作成ができません。`playsinline` パラメータは付与しないようにしてください。
- YouTube 以外の動画URLや、埋め込み用でない YouTube の動画URLを入力した場合も、メッセージの作成ができません。
- `playsinline` 以外のパラメータを付与することは可能ですが、OSや端末によってはパラメータが効かない可能性もあるためご注意ください。

**見出し**
: メッセージのヘッダーを指定します。テキストの色を指定できます。

**本文**
: メッセージの本文を指定します。テキストの色を指定できます。

**アクションボタン**
: アクションボタンに表示するテキストを指定します。ボタンの背景色とテキストの色が指定できます。

**ディープリンクもしくはURL (任意)**
: URLを指定するとボタンを押した時に指定したURLのページを開くことができます。URLを指定しないでボタンを押した場合はただアプリ内メッセージが閉じます。
   
  - 文字列長
    - 最大: 1000文字
   
  ディープリンクは以下3種類のディープリンクに対応しています。
   
  - ユニバーサルリンク
  - アプリリンク
  - カスタムURL Scheme
   
  ユニバーサルリンクとアプリリンクを指定したい場合は、 [ディープリンクに、ユニバーサルリンク（iOS）やアプリリンク（Android）を利用する場合](https://docs.repro.io/ja/dashboard/campaign/push-notification.md#clear-badge-setting) をご確認ください。

**トラッキングイベント名 (任意)**
: トラッキングイベント名を指定すると、アクションボタンをクリックしたときに計測されるイベントを変更することができます。

#### アンケート埋め込み(Googleフォーム)

Googleフォームをメッセージ内に埋め込むことができます。

##### NOTE
- このテンプレートの利用には、Repro iOS SDK 5.2.0 以上かつ iOS 13 以上、もしくはRepro Android SDK 5.1.0 以上かつ Android 5 以上が必要です。対象未満のバージョンには、メッセージは配信されません。
- アンケートの公開が終了しているなどの理由で、配信されたメッセージ内のアンケートが表示できない場合があります。特にメッセージの配信期間を長期間に設定する場合はアンケートが表示可能な状態であることを定期的に確認するようにしてください。

下記のフォームに入力してアプリ内メッセージを作成します。



**背景色**
: メッセージが表示される外側の領域の背景色を指定します。

**閉じるボタン**
: メッセージを閉じるボタンの色を指定します。

**Googleフォーム URL**
: メッセージに表示する Google フォームのURLを指定します。指定するURLは、埋め込み用のURLを入力してください。以下キャプチャはGoogleフォームの **送信** より、埋め込み用URLを取得した場合です。
   
  - 文字列長
    - 最大: 2000文字



##### NOTE
- Googleフォーム URLは `https://docs.google.com/forms/d/e/{form_id}/viewform` の形式に沿う必要があります。形式が異なる場合はメッセージの保存ができません。
- パラメータとして `embedded=true` が指定されている必要があります。指定されていない場合は、メッセージの保存ができません。
- `embedded` 以外のパラメータを付与することは可能ですが、OSや端末によってはパラメータが効かない可能性もあるためご注意ください。

#### オリジナル

テンプレートを利用せずに、HTML と CSS を用いてゼロからアプリ内メッセージのコンテンツを作成したい場合に利用できます。
詳細は、[HTMLアプリ内メッセージ](https://docs.repro.io/ja/dashboard/campaign/html-in-app-message.md) をご覧ください。



#### シルバーエッグ

シルバーエッグ・テクノロジー社のレコメンドサービスと連携して、エンドユーザー毎に異なるコンテンツを表示することができます。
詳細は、 [シルバーエッグレコメンドメッセージ](https://docs.repro.io/ja/dashboard/campaign/silver-egg-recommend-message.md) をご覧ください。

##### NOTE
- ご利用の際には弊社営業、もしくはカスタマーサクセス担当までご連絡ください。



#### 広告連動メッセージ



広告連動メッセージは、AppsFlyer/Adjustから取得したアトリビューションデータを利用して、広告から流入したユーザーに対して、
アプリ初回起動時に広告のクリエイティブと連動したアプリ内メッセージを表示することが可能です。

例えば広告Aをクリックしてアプリをインストールしたユーザーにはアプリ内メッセージAを、広告Bの場合はアプリ内メッセージBといったように
広告のクリエイティブと初回起動時のアプリ内メッセージを組み合わせることでシームレスなオンボーディング体験を提供出来ます。

**アプリの実装方法**

この機能を利用するには、SDKの実装が必要です。 [AppsFlyer](https://docs.repro.io/ja/dev/sdk/integrate-appsflyer.md)、[Adjust](https://docs.repro.io/ja/dev/sdk/integrate-adjust.md) のドキュメントを参考に、イベントプロパティに広告のアトリビューションデータをセットします。
一度アトリビューションのデータをイベントプロパティとしてセットする実装をしておくと、その後広告を新規に配信してもその度にアプリをアップデートする必要はありません。

**設定手順**


1. アプリの実装をした上で、どのアトリビューションデータを利用してメッセージを表示するかを決定し、 [イベント実行時のイベントプロパティの値によってトリガーを実行する](#inapp-complex-trigger-event-property) を利用してメッセージを表示します。

上の画像の例だとAdjustのAdgroupに `sample1234` が含まれる場合にメッセージを表示します。
SDKでセットした値であれば、どのキャンペーン構造のパラメータでもメッセージを表示出来ます。

1. 配信対象設定は `初回ユーザー` を指定します。

##### NOTE
- 動作確認の際は、広告IDをリセットした上でAppsFlyer/Adjustのトラッカー経由でアプリをインストールし、表示を確認してください。

##### WARNING
- iOSで、IDFAが取得出来ない場合、アトリビューションデータの精度によっては別の広告をクリックしたユーザーのメッセージが表示される可能性があります。

### キャンペーンをニュースフィードとして利用する

[キャンペーン設定](#inapp-campaign-settings) にて、キャンペーンをニュースフィードとして使うにチェックを入れた場合は、下記の画像のようなニュースフィード用の入力フォームがコンテンツ作成用のフォームの下に出現し、設定が可能です。詳細は [ニュースフィード](https://docs.repro.io/ja/dashboard/campaign/newsfeed.md) をご覧ください。



**タイトル**
: ニュースフィードのタイトルを指定します。ここで入力した値は、ニュースフィード内の `title` として取得が可能です。

**概要**
: ニュースフィードの概要を指定します。ここで入力した値は、ニュースフィード内の `summary` として取得が可能です。

**詳細（任意）**
: ニュースフィードの本文を指定します。ここで入力した値は、ニュースフィード内の `body` として取得が可能です。

**リンク先URL（任意）**
　ニュースフィードのリンク先となるURLを指定します。ここで入力した値は、ニュースフィード内の `link_url_string` （SDK） `link_url` （ニュースフィードAPI）として取得が可能です。

**画像（任意）**
　ニュースフィードに紐づく画像を指定します。ここでアップロードした画像のURLまたは入力したURLの値は、ニュースフィード内の `image_url_string` （SDK） `link_url` （ニュースフィードAPI）として取得が可能です。

### 配信対象者を各パターンに振り分ける



[配信対象を選択する](#inapp-select-target) で設定した配信対象者をコントロールグループと、パターン1に振り分けます。
コントロールグループ(統制群)とは、 **アプリ内メッセージを表示しない対象者** を指します。
キャンペーン自体の効果を計測するために、 **アプリ内メッセージを表示するユーザー** と **アプリ内メッセージを表示しないユーザー** で効果を比較できます。
パターンを増やした状態での設定方法は、 [A/Bテスト](#inapp-ab) をご覧ください。

例えば、配信条件を **既存ユーザー** とした場合に、コントロールグループを **20%** 、 パターン1を **80%** に設定すると、既存ユーザーの中からランダムで抽出された **約80%** のユーザーにメッセージが表示され、残りの **約20%** のユーザーにはメッセージは表示されません。

#### 割合を設定する

デフォルトではコントロールグループ **0%**、パターン1 **100%** となっているため、配信条件で指定したユーザーに **100%** 表示されます。
コントロールグループを利用しない場合は、設定を変更する必要はありません。
コントロールグループを利用する場合は、コントロールグループとパターン1で合計100%となるように割合を設定出来ます。

**均等に振り分ける** をクリックすると、コントロールグループとパターン1を **50%** ずつに均等に振り分けます。
**均等に振り分ける(コントロールグループなし)** をクリックすると、コントロールグループを **0%**、パターン1を **100%** に設定します。

##### NOTE
- コントロールグループは **0%** ~ **99%** まで設定出来ます。
- パターン1は **1%** ~ **100%** まで設定出来ます。
- 整数のみ設定出来ます。
- 振り分け設定は新規作成時のみ行うことが出来ます。
- インプレッションの規模により、設定した割合と実際のインプレッションが乖離することがあります。



### 配信設定

**配信期間**
: キャンペーンを配信する期間を設定してください。ここで設定した期間、メッセージがユーザーごとに一度だけ表示されます。ユーザーは [ユーザーID](https://docs.repro.io/ja/dev/sdk/user-id.md) で区別されます。

**表示頻度**
: メッセージが表示される頻度を制御できます。
   
  **1ユーザーに1回のみ表示**
   
  デフォルトでは1ユーザーに1回のみメッセージが表示されます。
   
  **1ユーザーに複数回表示**
   
  1ユーザーに複数回表示を選択すると、1ユーザーに対して複数回メッセージを表示することができます。
   
  例えば: 累計の表示回数を3回に制限したい場合、以下のように設定します。
   
  
   
  また上記の設定の場合、メッセージ表示トリガーに設定したイベントが1日に3回発生した場合、1日に同一のアプリ内メッセージが3回表示されますが、
  例えば累計は3回、1日の表示回数を1回に制限したい場合は、以下のように設定します。
   
  
   
  #### WARNING
  - 累計で最大 **無制限** 回に制限する を指定した場合、メッセージは無制限に表示され続けます。
  - 1ユーザーに複数回表示する場合、累計の最大回数の指定は必須となります。
  - 1日の最大回数は任意の設定となります、制限する場合はチェックボックスにチェックを入れてキャンペーンを公開してください。
  - 1ユーザーに複数回表示する場合、メッセージが表示されてから、Repro内部でメッセージが表示されたことを検知するまではメッセージが表示されません。

**表示優先度を調整する**
: メッセージの表示優先度を指定することができます。
  複数のキャンペーンで同一の配信トリガーが設定され、表示タイミングが競合した場合、表示優先度が高いキャンペーンのメッセージが優先的に表示されます。
   
  「表示優先度を調整する」のチェックボックスをオンにすると、優先度を入力するフォームが表示されます。
   
  
   
  **優先度の指定方法**
   
  優先度は **1** から **100** までの数値で指定でき、数値が大きいほど優先して表示されます。
   
  **デフォルトの優先度について**
   
  チェックボックスがオフの状態では、優先度は **50** として扱われます。また、本機能がリリースされる前に作成された既存のキャンペーンについても、優先度は一律で **50** として扱われます。
   
  **優先度が同じ場合の挙動**
   
  競合するキャンペーン間で表示優先度が同じ値（共に未設定の場合も含む）の場合、**更新日時が最も新しいキャンペーン** のメッセージが優先して表示されます。
   
  #### NOTE
  - 本機能の利用には、iOS SDK 5.23.0 以上 および Android SDK 5.21.0 以上 が必要です。
  - 対象未満の古いバージョンのSDKを利用している端末に対しては、設定した優先度の値は適用されません（仮に値が設定されていても、すべてのキャンペーンが同じ優先度として扱われ、更新日時が新しいものが優先されます）。



### メッセージ表示トリガー

メッセージ表示トリガーによってメッセージの表示タイミングを制御することができます。
ユースケースによって以下の設定を行います。

#### イベント実行時にトリガーを実行する

指定したイベントが実行された場合にトリガーします。



**トリガーの種類**
: **イベントの実行** を選択します。

**トリガー**
: 1. 最初の選択リストからイベントを指定します。
  2. 次の選択リストから **実行時** を指定します。

#### イベントの合計実行回数によってトリガーを実行する

指定したイベントが特定の回数だけ実行された場合にトリガーします。



**トリガーの種類**
: **イベントの実行** を選択します。

**トリガー**
: 1. 最初の選択リストからイベントを指定します。
  2. 次の選択リストから **合計実行回数** を指定します。

**条件**
: - 合計実行回数
    - 数値は、最小2から最大30まで指定できます。
  - 集計対象期間
    - 「セッション内」のみが対象となります。

##### WARNING
- 複数端末で同一ユーザーIDを設定している場合、端末毎に合計値を計算します。
- 同一イベントで、かつ、合計実行回数が同じ値で複数のキャンペーンを設定した場合、一つのセッション内でトリガーできるメッセージは一つだけとなります。



#### イベント実行時のイベントプロパティの値によってトリガーを実行する

指定したイベントプロパティが特定の値であった場合にトリガーします。



**トリガーの種類**
: **イベントの実行** を選択します。

**トリガー**
: 1. 最初の選択リストからイベントを指定します。
  2. 次の選択リストからイベントプロパティのキーを指定します。

**条件**
: - イベントプロパティの条件となる値を指定します。
  - 比較方法は「と一致する」、「と一致しない」、「のいずれか」、「以上（数値）」、「以下（数値）」、「を含む（文字列）」から選択可能です。

##### WARNING
- イベントプロパティの値が小数で、「と一致する」もしくは「と一致しない」で設定した場合、端数処理の関係でトリガーしない可能性があります。

#### ユーザープロフィールのセットによってトリガーを実行する

ユーザープロフィールがセットされた際に、セットされる値が特定の値であった場合にトリガーします。



**トリガーの種類**
: **ユーザープロフィールのセット** を選択します。

**トリガー**
: 1. ユーザープロフィールを指定します。

**条件**
: - セットされる値
    - セットされる値を指定します。
    - 一致する場合のみ有効です。
    - セット前の値を指定することはできません。
    - セット前と同じ値がセットされた場合でもトリガーが実行されます。

##### NOTE
- 「日付」で登録されているユーザープロフィールは、指定することができません。

##### WARNING
- iOS SDKバージョン5.22.0、Android SDKバージョン5.20.6以前では、 [ユーザープロフィールの条件付きセット操作](https://docs.repro.io/ja/dev/sdk/user-profile.md#user-profile-conditional-set) で一致する値がセットされた場合、または [ユーザープロフィールの増加値/減少値](https://docs.repro.io/ja/dev/sdk/user-profile.md#user-profile-increment-and-decrement) が  *セットされる値* と一致する場合でもトリガーが実行されます。ご注意ください。

##### NOTE
- iOS SDKバージョン5.22.1、Android SDKバージョン5.20.7以降は [ユーザープロフィールの条件付きセット操作](https://docs.repro.io/ja/dev/sdk/user-profile.md#user-profile-conditional-set) で一致する値がセットされた場合、または [ユーザープロフィールの増加値/減少値](https://docs.repro.io/ja/dev/sdk/user-profile.md#user-profile-increment-and-decrement) で計算結果が一致した場合でもトリガーは発火しません。



### 配信対象を選択する



イベントやユーザープロフィール、全ユーザーといったセグメンテーションフィルターをつかって、配信対象となるユーザーを指定できます。各フィルターは **and** 、 **and not** 、 **or** を使って、最大5個まで組み合わせられます。

- **and**: 指定した条件を全て満たすユーザーが対象になります
- **and not**: 指定した条件にあてはまるユーザーが対象から除外されます
- **or**: 指定した複数の条件のどれかにあてはまるユーザーが対象になります

例えば:

- 3日前にアプリを使用して、その後2日間アプリを使っていないユーザーへ配信する場合


- 性別が女性で直近3日以内にイベントAかイベントBのどちらかを実行したユーザーへ配信する場合



#### オーディエンスでフィルタリング

[オーディエンス](https://docs.repro.io/ja/dashboard/campaign/audience.md) で作成したセグメンテーションを利用することができます。

##### NOTE
- フィルターオーディエンス: 他のフィルタリング条件と組み合わせることはできません。
- インポートオーディエンス: 他のフィルタリング条件と組み合わせることができます。

#### イベントでフィルタリング

[イベント](https://docs.repro.io/ja/dev/sdk/tracking.md) を実行したユーザーをセグメンテーションすることができます。実行した期間や回数を指定することができます。

#### イベントプロパティでフィルタリング

[イベント](https://docs.repro.io/ja/dev/sdk/tracking.md) を実行したユーザーのうち、実行されたイベントに付帯するプロパティにもとづいてユーザーをセグメンテーションすることができます。プロパティの名前や値、実行した期間や回数を指定することができます。

#### ユーザープロフィールでフィルタリング

[ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md) に登録されている情報にもとづいてユーザーをセグメンテーションすることができます。SDKでプロフィールの型に数値を指定している場合、「以上、以下、より大きい、より小さい」などをつかって、値を比較する条件を指定できます。文字を指定している場合、「一致する、一致しない、含む」などをつかって、条件を指定できます。日付を指定している場合、「◯日前以前、◯日前〜▢日前、特定日以前」などをつかって、条件を指定できます。

日付の指定については、[サポートサイトのFAQ](https://support.repro.io/hc/ja/articles/23886462974489) に詳細な説明がありますので、こちらも参考にしてください。

#### 全ユーザー

Reproへの登録の有無に関わらず、全てのユーザーが対象になります。全ユーザーを利用する場合は、**その他の条件をフィルターに使うことができません** ので、ご注意ください。

#### 既存ユーザー

Reproに登録されたすべてのユーザーが対象となります。既存ユーザーから特定条件を満たすユーザーを除外する場合は、 **and not** でフィルターを追加してください。



#### 初回ユーザー

アプリを初めて起動したユーザーを対象にメッセージを配信します。

##### NOTE
- アプリをインストールしてから1週間以上経って初めてアプリを起動した場合は初回ユーザーとして判定されないのでご注意ください。



### 下書きとして保存

キャンペーンの必須項目をすべて記入していない状態など、キャンペーンの作成途中で作成を終えたい場合は、 **下書きで保存** をクリックしてください。
下書きで保存をした場合は、後からキャンペーンのゴールやメッセージのパターンを変更することができます。

下書き状態のキャンペーンはメッセージ一覧画面の下書きタブから選択できます。





### 公開、もしくは、非公開にする

公開もしくは非公開をクリックする前に、設定したキャンペーンの内容を注意深くチェックしてください。
キャンペーンを公開、非公開で登録後からキャンペーンのゴール、メッセージのパターン が **変更できなくなります。**

確認後、キャンペーンを公開する準備が整っていれば、 **公開** を、そうでない場合は **非公開** をクリックしてください。

##### NOTE
- アプリ内メッセージは、1キャンペーンあたり対象ユーザーに1度だけメッセージが表示されます。あるユーザーが複数デバイスを持っている場合、一度どちらかのデバイスでアプリ内メッセージを表示するともう片方のデバイスではアプリ内メッセージは表示されません。
- 配信トリガーが同じ複数のキャンペーンを公開する場合、更新日時が新しいものから表示されます。



### 効果測定

キャンペーンの効果を確認できます。



##### NOTE
- この画面は 2016年10月14日 以降に作成されたキャンペーンにのみ適用されます。



#### 配信結果

**インプレッション**
: アプリ内メッセージが表示されたユーザー数を日次で集計し、合計した数です。

**コンバージョン数**
: 表示から24時間以内に、作成画面で指定したゴールを達成したユーザーの数を日次で集計し、合計した数です。

**コンバージョン率**
: コンバージョン数 / インプレッション です。

**結果の推移**
: キャンペーン実施期間中のインプレッション、コンバージョン数を日次で集計した結果を表示しています。計測単位はユーザーです。



### A/Bテスト

配信対象に指定したユーザーに複数のパターンのメッセージを均等に出し分けることで、どのようなメッセージを配信すればコンバージョン率が向上するのかを検証することができる機能です。

最も効果の高かったメッセージを勝ちパターンとして指定することができます。

#### メッセージ作成

メッセージのパターンを2個以上作成することで、A/Bテストを行うことができます。


- メッセージは最大4パターンまで追加することができます。
- パターンの追加や削除は新規作成時のみ行うことができます。

#### 配信対象者を各パターンに振り分ける



パターンを2つ以上に設定した場合も、各パターンに配信対象者を振り分けられます。
コントロールグループを含む各パターンの合計が100%になるように設定します。

**均等に振り分ける** をクリックすると、コントロールグループと各パターンを均等に振り分けます。
**均等に振り分ける(コントロールグループなし)** をクリックすると、コントロールグループを **0%** に設定し、 **100%** を各パターンで均等に振り分けます。

##### NOTE
- コントロールグループは **0%** ~ **99%** まで設定出来ます。
- 各パターンは **1%** ~ **100%** まで設定出来ます。
- 整数のみ設定出来ます。
- 振り分け設定は新規作成時のみ行うことが出来ます。
- インプレッションの規模により、設定した割合と実際のインプレッションが乖離することがあります。



#### 効果測定（A/Bテスト）

**詳細画面**

インプレッションやコンバージョン数が計上されると効果測定結果が表示されます。グラフにはアプリ内メッセージのインプレッション、各ボタンの押下数、コンバージョン率がパターンごとに表示されています。キャンペーンのデータ更新タイミングについての詳細は [こちら](https://docs.repro.io/ja/dashboard/misc/aggregation.md) をご覧ください。



##### NOTE
- コントロールグループの各データはキャンペーン自体の効果を判断しやすくするため、キャンペーン全体の **インプレッション**、**コンバージョン数**、**コンバージョン率** には反映されません。
- コントロールグループに属するユーザーにはアプリ内メッセージは配信されないため、インプレッション、ボタン1押下数、ボタン2押下数は常に **-** で表示されます。
- コントロールグループのコンバージョン数は、コントロールグループに属するユーザーがキャンペーンに設定したゴールのイベントを発生させた数を表示します。
- コントロールグループのコンバージョン率は、コンバージョン数をコントロールグループに属するユーザー数で割って算出されます。

なおメッセージのタイプによってボタン押下として計上される端末上の操作が異なります。それぞれのボタン押下数の定義については下記の通りです。

| メッセージタイプ | ボタン1押下数の定義 | ボタン2押下数の定義 |
| --- | --- | --- |
| ダイアログ | ボタン1がタップされた数 | ボタン2がタップされた数 |
| ダイアログ（画像のみ） | 画像がタップされた数 | なし |
| オーバーレイ | ボタン1がタップされた数 | ボタン2がタップされた数 |
| バナー | バナー部分がタップされた数 | なし |

A/Bテストの実行中にはA/Bテストの実行結果が表示されます。ここではコントロールグループを含む各パターンを選択した指標 (ボタン1押下率、ボタン2押下率、コンバージョン率) を用いて比較を行えます。



**パターン**

コントロールグループを含む、A/Bテストで送信を行う各パターンが表示されます。

**ベースライン**

A/Bテストで各パターンを比較する際に基準となるパターンをベースラインとして選択します。ベースラインを変更することで、様々なパターン間の比較ができます。

**対象となる指標**

A/Bテストで各パターンをベースラインと比較する際に用いる指標を選択します。指標には割合を表す値 (ボタン1押下率、ボタン2押下率、コンバージョン率) が選択できます。また、一覧に表示する指標については編集画面から変更できます。

**90%信頼区間**

各パターンをベースラインと比較した場合の 90% 信頼区間が表示されます。90% 信頼区間そのものの意味については [FAQ](https://docs.repro.io/ja/faq/general/significant-difference/5.md) をご参照ください。ここでは代表的なパターンの読み取り方について示します。

パターン１：



このような表示の場合、パターンとベースラインとの差が有意であることを意味します。配信を開始してから十分な期間が経過している場合、勝ちパターンの決定へと進むことを推奨します。

パターン２：



このような表示の場合、パターンとベースラインとの差が有意ではないことを意味します。結果が出るまでもう少し待つか、配信を開始してから十分な期間が経過している場合、差がないものとして次のキャンペーンの開始を検討することを推奨します。

パターン３：



このような表示の場合、パターンとベースラインとの差が有意であることを意味します。このような表示しかない場合、ベースラインとして設定しているパターンを勝ちパターンして決定することを推奨します。

パターン４：



このような表示の場合、そのパターンは指標の値が存在しないため、有意差の計算が不可能であることを意味します。

##### NOTE
- A/Bテスト有意差 測定結果は勝ちパターンを選択すると下記のような表示になり、各パターンの比較結果が表示されないようになります



**結果の推移**

グラフにはアプリ内メッセージのインプレッション、ボタン1押下数、ボタン2押下数、コンバージョン率がパターンごとに表示されています。



**一覧画面**

A/Bテストを実行しているキャンペーンが公開中または非公開の場合に、一覧画面で各キャンペーンのA/Bテストの状態を確認できます。
アイコンの表示条件は次のとおりです。

| アイコン | 表示条件 |
| --- | --- |
|  | 有意差があり、ベースラインを上回る結果のパターンが1つ以上存在する場合 |
|  | 有意差があり、ベースラインを下回る結果のパターンのみが存在する場合 |
|  | 有意差がないパターンのみが存在する場合 |
|  | 全てのパターンで計算ができない場合 |
|  | 勝ちパターンを選択済みの場合 |
|  | A/Bテストを実行していて、ベースラインとなるパターンか対象となる指標が設定されていない場合 |
| ー | キャンペーンがA/Bテストを実行していない場合 |

##### NOTE
- 有意差があり、ベースラインを上回る結果と下回る結果のキャンペーンが両方ともに存在する場合には、ベースラインを上回る結果が1つでも存在する場合として表示がされます
- ご不明点がある場合 [FAQ](https://docs.repro.io/ja/faq/general/index.md) もあわせてご確認ください

#### 勝ちパターンを選ぶ

勝ちパターンを選ぶと、以降はそのパターンのみが配信対象のユーザーに配信されるようになります。

---

## HTMLアプリ内メッセージ

##### WARNING
- HTMLアプリ内メッセージの利用時は、必ずHTML/CSS/JavaScriptの知識・経験の豊富な人が操作・編集を行ってください。
- テンプレートの内容をそのまま利用しない限り、HTMLアプリ内メッセージの編集画面上でレスポンシブ対応に必要なCSSやアニメーションのCSSの記述はございません。必要に応じて適宜ご準備ください。

### HTMLアプリ内メッセージを作成する

HTMLアプリ内メッセージを作成する方法は2種類あります。

#### スタンダードテンプレートを利用する

1. 配信したいメッセージをテンプレートの一覧から選択し、アプリ内メッセージの作成画面でタイプにある **カスタム** を選択します。


1. カスタムボタンを押下すると、テキストエディタが画面左側に表示されます。選択したテンプレートのHTML、CSSがそのままセットされていますので、必要に応じてHTMLやCSSを編集してください。



##### NOTE
- スタンダードで入力されたテキストの内容は画像も含めカスタムへ引き継がれます。
- カスタムで編集した内容はスタンダードへ引き継がれません。また、カスタム編集中にスタンダードへ変更するとカスタムで編集した内容は破棄されます。

#### オリジナルテンプレートを利用する

テンプレートの一覧からオリジナルテンプレート(ID1000)を選択します。



### HTMLアプリ内メッセージを編集する

#### パターンを複製する

1. メッセージ項目にある **追加** ボタンを押下し、 **パターンを複製** ボタンを押下します。


1. 複製されたパターンが表示されるので、エディタからメッセージを編集します。なお、HTMLアプリ内メッセージでパターンを複製した場合は、スタンダードタイプのメッセージに変更することはできません。

#### HTMLアプリ内メッセージを複製する

1. 複製したいメッセージを選択し、複製ボタンを押下します。なお、複製元がHTMLアプリ内メッセージの場合はスタンダードタイプのメッセージに変更することはできません。


1. メッセージ編集画面に遷移後、エディタからメッセージを編集します。



### コンテンツを編集する

コンテンツを編集します。
HTMLは以下のルールに沿って編集してください。

- トップレベルが単一の要素となるよう記述してください。

```html
<!-- Good -->
<div>
  <div>message1</div>
  <div>message2</div>
</div>

<!-- Bad -->
<div> message1</div>
<div> message2</div>
```

- トップレベルがタグで囲まれた要素となるよう記述してください。

```html
<!-- Good -->
<p>message</p>

<!-- Bad -->
message
```

#### メッセージを非表示にする要素を設定する

1. 対象要素に `data-repro--close` 属性を追加してください。

```html
<div class="btn" data-repro--close> ☓ </div>
```

#### 効果測定で計測されるアクションボタンを設定する

アクションボタンに属性を設定することで、任意の要素へのクリックなどを効果測定の配信結果に表示される **ボタン1押下数** 、 **ボタン2押下数** として集計することが可能です。

1. ボタン1・2押下数として効果測定したい要素に対して、それぞれ `data-repro--primary-btn` と `data-repro--secondary-btn` の属性を付与します。

```html
<div class="btn" data-repro--primary-btn>button_1</div>
<div class="btn" data-repro--secondary-btn>button_2</div>
```

1. ボタン1・2をクリックした場合のトラッキングイベント名を指定する場合は、それぞれ `data-repro--primary-cta-event` と `data-repro--secondary-cta-event` の属性を付与します。

```html
<div class="btn" data-repro--primary-btn data-repro--primary-cta-event="tap_button_1">button_1</div>
<div class="btn" data-repro--secondary-btn data-repro--secondary-cta-event="tap_button_2">button_2</div>
```

##### NOTE
- `data-repro--primary-cta-event` および `data-repro--secondary-cta-event` は同一の HTML 内で2回以上設定することはできません。
- `data-repro--primary-cta-event` および `data-repro--secondary-cta-event` の属性を付与しない場合は、トラッキングイベント名として `in_app_message` が設定されます。
- `data-repro--primary-cta-event=""` と記述した場合は、トラッキングイベント名として `in_app_message` が設定されます。`data-repro--primary-secondary-event=""` と記述した場合は、トラッキングイベント名は設定されず、要素をクリックしてもイベントは発火しません。

#### HTMLアプリ内メッセージで画像を設定する

1. メッセージで画像を利用する場合は、HTML上で挿入したい位置にカーソルを合わせ、テキストエディタ下部にある **画像を追加** ボタンを押してください。なお、画像付テンプレートの場合は、カーソルを指定しなくてもテンプレート上の画像の位置に自動で画像が追加されます。


1. パソコン上のフォルダから画像を選択して画像をアップロードすると、指定したカーソルの位置に `img src=` のタグと画像のURLが生成され、プレビュー上にも画像が反映されます。



##### NOTE
- **画像を追加** ボタンでアップロードできる画像ファイルサイズは最大1MBです。なお、 **画像を追加** ボタンを用いなければ、利用できる画像サイズに制限はありませんが、推奨画像サイズは変わらず最大1MBです。
- 画像の無いテンプレートを選択して **画像を追加** ボタンを利用する場合、`<div class="repro-xxxx--container">` のタグ内にカーソルを指定してください。同タグ内にカーソルを指定しない場合、HTML構文の最終行に `img src=` のタグと画像のURLが生成され、メッセージの外に画像がアップロードされることになります。
- 管理画面上のプレビューは作成画面上のものとなるため、実機でも見た目をご確認ください。



### HTMLアプリ内メッセージでJavaScriptを利用する

HTMLアプリ内メッセージでは **script** タグを利用してJavaScriptを記述することができます。JavaScriptでよりリッチな表現が可能になります。
ID1000のテンプレートのみ、JavaScriptを記述する専用のフォームがあります。ID1000以外のテンプレートではカスタムに変更しHTMLに **script** タグを記述して下さい。
ここではID1000のテンプレートでのJavaScriptについて利用方法を説明します。

##### WARNING
- HTMLアプリ内メッセージでJavaScriptを利用するには、Repro iOS SDK 5.5.0以上かつ iOS 9 以上、もしくはRepro Android SDK 5.4.0 以上かつ Android 5 以上を利用してください。対象バージョン未満では、JavaScriptが動作しません。
- 本機能を利用することで生じた一切の損失に関して、当社は責任を負いかねます。詳しくはRepro利用規約([https://repro.io/company/legal/term/](https://repro.io/company/legal/term/))をご確認ください。

#### **導入手順**

1. [アプリ内メッセージ](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md) を参考にしてメッセージを作成してください。その際、ID1000のテンプレートを選択して下さい。
2. 1.で作成したメッセージの編集画面のコンテンツでJavaScriptを選択してJavaScriptを編集をすることができます。



実装例に関して、ご希望の方は、管理画面右下のチャットもしくは弊社の営業担当へお問い合わせください。

##### NOTE
- 当該のスクリプトは **ローカルな関数スコープとして実行されます** ので、ご注意ください。
- 当該のスクリプトに対する **トランスパイルの処理は行われません** ので、ご注意ください。
- JavaScriptとして記述する内容については一切の制限を行いませんが、jQueryなどのライブラリはロードしません。
- JavaScriptエディター内のLinterは、JSHintを使用しています。

1. 思った通りの動きを実現出来ているかをプレビューの機能を使って、確認することが出来ます。



##### NOTE
- 管理画面上のプレビューは作成画面上のものとなるため、実機でも見た目をご確認ください。
- ID1000以外のテンプレートでは、JavaScriptのフォームはご利用になれません。
- ID1000以外のテンプレートでJavaScriptを利用する場合はカスタムに変更しHTMLに直接 **script** タグを記述してください。
- HTMLアプリ内メッセージで **script** タグを利用するには、Repro iOS SDK 5.5.0以上かつ iOS 9 以上、もしくはRepro Android SDK 5.20.2 以上かつ Android 5 以上を利用してください。対象バージョン未満では、 **script** タグ内に書かれたJavaScriptが動作しません。



#### **HTMLアプリ内メッセージでイベントトラッキングおよびユーザープロフィールの設定を行う**

JavaScriptを用いて処理を記述することで、任意のイベントのトラッキングやユーザープロフィールの設定を行うことができます。

**実装例**

以下のスクリプトはあくまでサンプルになりますので、その旨ご了承の上ご利用ください。

フォームに入力されたメールアドレスをユーザープロフィールに登録する例

```js-inapp
// Email address input form
var email = document.getElementById("email-form");
// Register button
var registerButton = document.getElementById("register-button");
// Register the e-mail address to user profile
registerButton.onclick = function() {
    Repro.setUserEmailAddress(email.value);
    // Close the in-app message
    Repro.closeDialog();
}
```

その他、詳細な利用方法については [ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md) および [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md) を参照してください。

##### WARNING
- HTMLアプリ内メッセージでの任意のイベントのトラッキングおよびユーザープロフィールの設定を行うには、iOS SDK 5.19.0 以上 および Android SDK 5.18.0 以上を利用する必要があります。



#### **HTMLアプリ内メッセージでイベントプロパティの取得を行う**

JavaScriptを用いて処理を記述することで、アプリ内メッセージを開いた際のトリガーとなったイベントのプロパティを取得することができます。

**実装例**

ショップ画面を開いたときにイベントをトラックし、そのイベントをトリガーとして表示されたアプリ内メッセージの中で ユーザーの居住地に応じた画像を表示する例

```
// This is a sample of an application being developed in Java

// Runs when the store page is opened
Map<String, Object> properties = new HashMap<>();
properties.put("residenceArea", "tokyo");
Repro.track("openedStorePage", properties); // Shows an in-app message
```

```js-inapp
// Replace the src property of a <img src=""> tag according to the user's location
document.getElementById("topImage").src = "https://example.com/img/area/" + Repro.triggeredEventProperties.residenceArea + ".jpg";
```

##### WARNING
- HTMLアプリ内メッセージ内でイベントプロパティの取得を行うには、iOS SDK 5.19.0 以上 および Android SDK 5.18.0 以上を利用する必要があります。

### HTMLアプリ内メッセージで動画を再生する

HTMLアプリ内メッセージではHTMLに **video** タグを記述することで動画を配信することができます。

##### IMPORTANT
- iOSアプリを対象に **video** タグを含んだHTMLアプリ内メッセージを配信する場合は必ず `playsinline` 属性を付けてください。
- iOSアプリでは `playsinline` 属性を付けない場合は全画面で再生されます。

##### WARNING
- HTMLアプリ内メッセージで **video** タグを利用するには、Repro iOS SDK 5.5.0以上かつ iOS 9 以上、もしくはRepro Android SDK 5.4.0 以上かつ Android 5 以上を利用してください。対象バージョン未満では、 **video** タグは動作しません。
- 本機能を利用することで生じた一切の損失に関して、当社は責任を負いかねます。詳しくはRepro利用規約([https://repro.io/company/legal/term/](https://repro.io/company/legal/term/))をご確認ください。

**実装例**

表示されたアプリ内メッセージの中で商品紹介動画を自動で再生する例

```html
<video playsinline loop muted autoplay src="https://example.com/your/product/id/promotion.mp4" width="100%">
</video>
```

### その他の設定

配信設定などのその他のメッセージ設定につきましては、 [アプリ内メッセージ](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md) をご確認ください。

---

## ユーザープロフィール

ユーザープロフィールは、性別、年齢、地域、言語、会員種別など、アプリで収集可能なユーザーの付帯情報です。

このプロフィール情報を基にして、対象となるユーザーを絞り込んでプッシュ通知やメッセージを送信することができるようになります。

それぞれのプロフィール情報は固有のユーザーIDにひもづけられます。プロフィール情報をセットする前に、 [ユーザーIDをセットする](https://docs.repro.io/ja/dev/sdk/user-id.md) ことをおすすめします。ユーザーIDがセットされていない場合は、匿名ユーザーの情報として扱われ、Reproが任意に設定したIDにひもづけられますが、匿名のユーザーIDはアプリのアップデートやアンインストールによって変更されます。

##### WARNING
- 一度登録したユーザープロフィールキーやデータ型は、後から変更や削除をすることができません。
- ユーザープロフィール設定数に上限はありません。 但し、アナリティクスでの [フィルター](https://docs.repro.io/ja/dashboard/analytics/filter.md) や、キャンペーン機能で [ユーザープロフィールでフィルタリング](https://docs.repro.io/ja/dashboard/campaign/audience.md#audience-user-profile-filtering) する際には利用に上限があります。 現在の設定数は **設定 > ユーザープロフィール設定** で確認することができます。
- **ユーザープロフィール設定** では、プッシュ通知やメッセージなど、キャンペーン機能の対象者を絞り込むために利用できるユーザープロフィールの設定を変更することができます。ここで無効にしたユーザープロフィールは、キャンペーン作成画面やアナリティクス画面のユーザー情報による絞り込みの候補として表示されません。
- キャンペーン機能の対象者の絞り込みに利用できる上限を超えてユーザープロフィールを設定した場合は、ユーザープロフィールとして設定はされますがキャンペーン機能の絞り込みの候補としては表示されません。
- **ユーザープロフィール設定** でキャンペーン対象者の絞り込みに利用されているユーザープロフィールを無効にすると、該当するキャンペーンは配信されなくなります。

##### WARNING
- HTMLアプリ内メッセージでのユーザープロフィールの設定を行うには、iOS SDK 5.19.0 以上 および Android SDK 5.18.0 以上を利用する必要があります。
- WebViewにてユーザープロフィールの設定を行うには、iOS SDK 5.19.0 以上 および Android SDK 5.18.0 以上を導入し、かつ [バージョン6以上のrepro.js](/ja/dev/sdk/webview.html#web) を利用する必要があります。
- 条件付きセット、増減、削除の操作を行うには、iOS SDK 5.21.0、Android SDK 5.20.0、および [バージョン8以上のrepro.js](/ja/dev/sdk/webview.html#web) 以上を利用する必要があります。



### 標準ユーザープロフィール

Reproではユーザーを絞り込む上で典型的なプロフィールを **標準ユーザープロフィール** として定義しています。 **標準ユーザープロフィール** をセットする際は、情報の種類に応じたAPIを呼び出してください。また、アプリ独自のユーザープロフィールをセットする際は [カスタムユーザープロフィール](#custom-profile) をご利用ください。

##### WARNING
- 以下のバージョンでは、標準ユーザープロフィールとして性別およびEメールアドレスを登録することはできません。
  - Unity SDK 6.15.0 以下
  - Cordova Plugin 6.16.0 以下
- 標準ユーザープロフィールとして都道府県、生年月日および年齢の登録を行うためには以下のいずれかの SDK を利用する必要があります。
  - Android SDK 5.14.0 以上
  - iOS SDK 5.15.0 以上
  - Unity SDK 5.16.0 以上
  - React Native SDK 3.17.0 以上
  - Cordova Plugin 6.17.0 以上
  - Cocos2d-x SDK 5.16.0 以上
  - Flutter Package 3.8.0 以上

#### 性別

ユーザーの性別をセットします。指定できる性別はReproの定数として定義されています。

```objc
// set the gender as "male"
[Repro setUserGender:RPRUserProfileGenderMale];
// set the gender as "female"
[Repro setUserGender:RPRUserProfileGenderFemale];
// set the gender as "other"
[Repro setUserGender:RPRUserProfileGenderOther];
```

```swift
// set the gender as "male"
Repro.setUserProfile(gender: .male)
// set the gender as "female"
Repro.setUserProfile(gender: .female)
// set the gender as "other"
Repro.setUserProfile(gender: .other)
```

```java
// set the gender as "male"
Repro.setUserGender(UserProfileGender.MALE);
// set the gender as "female"
Repro.setUserGender(UserProfileGender.FEMALE);
// set the gender as "other"
Repro.setUserGender(UserProfileGender.OTHER);
```

```kotlin
// set the gender as "male"
Repro.setUserGender(UserProfileGender.MALE)
// set the gender as "female"
Repro.setUserGender(UserProfileGender.FEMALE)
// set the gender as "other"
Repro.setUserGender(UserProfileGender.OTHER)
```

```cpp
// set the gender as "male"
ReproCpp::setUserGender(ReproCpp::UserProfileGenderMale);
// set the gender as "female"
ReproCpp::setUserGender(ReproCpp::UserProfileGenderFemale);
// set the gender as "other"
ReproCpp::setUserGender(ReproCpp::UserProfileGenderOther);
```

```csharp
// set the gender as "male"
Repro.SetUserGender(UserProfileGender.Male);
// set the gender as "female"
Repro.SetUserGender(UserProfileGender.Female);
// set the gender as "other"
Repro.SetUserGender(UserProfileGender.Other);
```

```js-cordova
// set the gender as "male"
Repro.setUserGender(Repro.UserProfileGender.Male);
// set the gender as "female"
Repro.setUserGender(Repro.UserProfileGender.Female);
// set the gender as "other"
Repro.setUserGender(Repro.UserProfileGender.Other);
```

```js-react-native
// set the gender as "male"
Repro.setUserGender(Repro.GENDER_MALE);
// set the gender as "female"
Repro.setUserGender(Repro.GENDER_FEMALE);
// set the gender as "other"
Repro.setUserGender(Repro.GENDER_OTHER);
```

```js-webview
// set the gender as "male"
repro.setUserGender(repro.userProfileGender.Male);
// set the gender as "female"
repro.setUserGender(repro.userProfileGender.Female);
// set the gender as "other"
repro.setUserGender(repro.userProfileGender.Other);
```

```js-inapp
// set the gender as "male"
Repro.setUserGender(Repro.UserProfileGender.Male);
// set the gender as "female"
Repro.setUserGender(Repro.UserProfileGender.Female);
// set the gender as "other"
Repro.setUserGender(Repro.UserProfileGender.Other);
```

```dart
// set the gender as "male"
await Repro.setUserGender(UserGender.male);
// set the gender as "female"
await Repro.setUserGender(UserGender.female);
// set the gender as "other"
await Repro.setUserGender(UserGender.other);
```

プッシュ通知やアプリ内メッセージのフィルターを設定する際は、以下の表を参照し、文字列で指定してください。

| 性別 | フィルターに指定する値 |
| --- | --- |
| 男性 | male |
| 女性 | female |
| その他 | other |

#### Eメールアドレス

ユーザーのEメールアドレスをセットします。

```objc
[Repro setUserEmailAddress:@"user@example.com"];
```

```swift
Repro.setUserProfile(emailAddress: "user@example.com")
```

```java
Repro.setUserEmailAddress("user@example.com");
```

```kotlin
Repro.setUserEmailAddress("user@example.com")
```

```cpp
ReproCpp::setUserEmailAddress("user@example.com");
```

```csharp
Repro.SetUserEmailAddress("user@example.com");
```

```js-cordova
Repro.setUserEmailAddress("user@example.com");
```

```js-react-native
Repro.setUserEmailAddress("user@example.com");
```

```js-webview
repro.setUserEmailAddress("user@example.com");
```

```js-inapp
Repro.setUserEmailAddress("user@example.com");
```

```dart
await Repro.setUserEmailAddress("user@example.com");
```

#### 都道府県

ユーザーが居住している都道府県名をセットします。

```objc
// set the prefecture as "Tokyo"
[Repro setUserResidencePrefecture:RPRUserProfilePrefectureTokyo];

// Possible values are as follows:
//   RPRUserProfilePrefectureHokkaido, -Aomori, -Iwate, -Miyagi, -Akita, -Yamagata,
//   -Fukushima, -Ibaraki, -Tochigi, -Gunma, -Saitama, -Chiba, -Tokyo, -Kanagawa,
//   -Niigata, -Toyama, -Ishikawa, -Fukui, -Yamanashi, -Nagano, -Gifu, -Shizuoka,
//   -Aichi, -Mie, -Shiga, -Kyoto, -Osaka, -Hyogo, -Nara, -Wakayama, -Tottori,
//   -Shimane, -Okayama, -Hiroshima, -Yamaguchi, -Tokushima, -Kagawa, -Ehime, -Kochi,
//   -Fukuoka, -Saga, -Nagasaki, -Kumamoto, -Oita, -Miyazaki, -Kagoshima, -Okinawa
```

```swift
// set the prefecture as "Tokyo"
Repro.setUserProfile(residencePrefecture: .tokyo)

// Possible values are as follows:
//   .hokkaido, .aomori, .iwate, .miyagi, .akita, .yamagata,
//   .fukushima, .ibaraki, .tochigi, .gunma, .saitama, .chiba, .tokyo, .kanagawa,
//   .niigata, .toyama, .ishikawa, .fukui, .yamanashi, .nagano, .gifu, .shizuoka,
//   .aichi, .mie, .shiga, .kyoto, .osaka, .hyogo, .nara, .wakayama, .tottori,
//   .shimane, .okayama, .hiroshima, .yamaguchi, .tokushima, .kagawa, .ehime, .kochi,
//   .fukuoka, .saga, .nagasaki, .kumamoto, .oita, .miyazaki, .kagoshima, .okinawa
```

```java
// set the prefecture as "Tokyo"
Repro.setUserResidencePrefecture(UserProfilePrefecture.TOKYO);

// Possible values are as follows:
//   HOKKAIDO, AOMORI, IWATE, MIYAGI, AKITA, YAMAGATA,
//   FUKUSHIMA, IBARAKI, TOCHIGI, GUNMA, SAITAMA, CHIBA, TOKYO, KANAGAWA,
//   NIIGATA, TOYAMA, ISHIKAWA, FUKUI, YAMANASHI, NAGANO, GIFU, SHIZUOKA,
//   AICHI, MIE, SHIGA, KYOTO, OSAKA, HYOGO, NARA, WAKAYAMA, TOTTORI,
//   SHIMANE, OKAYAMA, HIROSHIMA, YAMAGUCHI, TOKUSHIMA, KAGAWA, EHIME, KOCHI,
//   FUKUOKA, SAGA, NAGASAKI, KUMAMOTO, OITA, MIYAZAKI, KAGOSHIMA, OKINAWA
```

```kotlin
// set the prefecture as "Tokyo"
Repro.setUserResidencePrefecture(UserProfilePrefecture.TOKYO)

// Possible values are as follows:
//   HOKKAIDO, AOMORI, IWATE, MIYAGI, AKITA, YAMAGATA,
//   FUKUSHIMA, IBARAKI, TOCHIGI, GUNMA, SAITAMA, CHIBA, TOKYO, KANAGAWA,
//   NIIGATA, TOYAMA, ISHIKAWA, FUKUI, YAMANASHI, NAGANO, GIFU, SHIZUOKA,
//   AICHI, MIE, SHIGA, KYOTO, OSAKA, HYOGO, NARA, WAKAYAMA, TOTTORI,
//   SHIMANE, OKAYAMA, HIROSHIMA, YAMAGUCHI, TOKUSHIMA, KAGAWA, EHIME, KOCHI,
//   FUKUOKA, SAGA, NAGASAKI, KUMAMOTO, OITA, MIYAZAKI, KAGOSHIMA, OKINAWA
```

```cpp
// set the prefecture as "Tokyo"
ReproCpp::setUserResidencePrefecture(ReproCpp::UserProfilePrefectureTokyo);

// Possible values are as follows:
//   UserProfilePrefectureHokkaido, -Aomori, -Iwate, -Miyagi, -Akita, -Yamagata,
//   -Fukushima, -Ibaraki, -Tochigi, -Gunma, -Saitama, -Chiba, -Tokyo, -Kanagawa,
//   -Niigata, -Toyama, -Ishikawa, -Fukui, -Yamanashi, -Nagano, -Gifu, -Shizuoka,
//   -Aichi, -Mie, -Shiga, -Kyoto, -Osaka, -Hyogo, -Nara, -Wakayama, -Tottori,
//   -Shimane, -Okayama, -Hiroshima, -Yamaguchi, -Tokushima, -Kagawa, -Ehime, -Kochi,
//   -Fukuoka, -Saga, -Nagasaki, -Kumamoto, -Oita, -Miyazaki, -Kagoshima, -Okinawa
```

```csharp
// set the prefecture as "Tokyo"
Repro.SetUserResidencePrefecture(UserProfilePrefecture.Tokyo);

// Possible values are as follows:
//   Hokkaido, Aomori, Iwate, Miyagi, Akita, Yamagata,
//   Fukushima, Ibaraki, Tochigi, Gunma, Saitama, Chiba, Tokyo, Kanagawa,
//   Niigata, Toyama, Ishikawa, Fukui, Yamanashi, Nagano, Gifu, Shizuoka,
//   Aichi, Mie, Shiga, Kyoto, Osaka, Hyogo, Nara, Wakayama, Tottori,
//   Shimane, Okayama, Hiroshima, Yamaguchi, Tokushima, Kagawa, Ehime, Kochi,
//   Fukuoka, Saga, Nagasaki, Kumamoto, Oita, Miyazaki, Kagoshima, Okinawa
```

```js-cordova
// set the prefecture as "Tokyo"
Repro.setUserResidencePrefecture(Repro.UserProfilePrefecture.Tokyo);

// Possible values are as follows:
//   Hokkaido, Aomori, Iwate, Miyagi, Akita, Yamagata,
//   Fukushima, Ibaraki, Tochigi, Gunma, Saitama, Chiba, Tokyo, Kanagawa,
//   Niigata, Toyama, Ishikawa, Fukui, Yamanashi, Nagano, Gifu, Shizuoka,
//   Aichi, Mie, Shiga, Kyoto, Osaka, Hyogo, Nara, Wakayama, Tottori,
//   Shimane, Okayama, Hiroshima, Yamaguchi, Tokushima, Kagawa, Ehime, Kochi,
//   Fukuoka, Saga, Nagasaki, Kumamoto, Oita, Miyazaki, Kagoshima, Okinawa
```

```js-react-native
// set the prefecture as "Tokyo"
Repro.setUserResidencePrefecture(Repro.PREFECTURE_TOKYO);

// Possible values are as follows:
//   PREFECTURE_HOKKAIDO, -AOMORI, -IWATE, -MIYAGI, -AKITA, -YAMAGATA,
//   -FUKUSHIMA, -IBARAKI, -TOCHIGI, -GUNMA, -SAITAMA, -CHIBA, -TOKYO, -KANAGAWA,
//   -NIIGATA, -TOYAMA, -ISHIKAWA, -FUKUI, -YAMANASHI, -NAGANO, -GIFU, -SHIZUOKA,
//   -AICHI, -MIE, -SHIGA, -KYOTO, -OSAKA, -HYOGO, -NARA, -WAKAYAMA, -TOTTORI,
//   -SHIMANE, -OKAYAMA, -HIROSHIMA, -YAMAGUCHI, -TOKUSHIMA, -KAGAWA, -EHIME, -KOCHI,
//   -FUKUOKA, -SAGA, -NAGASAKI, -KUMAMOTO, -OITA, -MIYAZAKI, -KAGOSHIMA, -OKINAWA
```

```js-webview
// set the prefecture as "Tokyo"
repro.setUserResidencePrefecture(repro.userProfilePrefecture.TOKYO);

// Possible values are as follows:
//   HOKKAIDO, AOMORI, IWATE, MIYAGI, AKITA, YAMAGATA,
//   FUKUSHIMA, IBARAKI, TOCHIGI, GUNMA, SAITAMA, CHIBA, TOKYO, KANAGAWA,
//   NIIGATA, TOYAMA, ISHIKAWA, FUKUI, YAMANASHI, NAGANO, GIFU, SHIZUOKA,
//   AICHI, MIE, SHIGA, KYOTO, OSAKA, HYOGO, NARA, WAKAYAMA, TOTTORI,
//   SHIMANE, OKAYAMA, HIROSHIMA, YAMAGUCHI, TOKUSHIMA, KAGAWA, EHIME, KOCHI,
//   FUKUOKA, SAGA, NAGASAKI, KUMAMOTO, OITA, MIYAZAKI, KAGOSHIMA, OKINAWA
```

```js-inapp
// set the prefecture as "Tokyo"
Repro.setUserResidencePrefecture(Repro.UserProfilePrefecture.TOKYO);

// Possible values are as follows:
//   HOKKAIDO, AOMORI, IWATE, MIYAGI, AKITA, YAMAGATA,
//   FUKUSHIMA, IBARAKI, TOCHIGI, GUNMA, SAITAMA, CHIBA, TOKYO, KANAGAWA,
//   NIIGATA, TOYAMA, ISHIKAWA, FUKUI, YAMANASHI, NAGANO, GIFU, SHIZUOKA,
//   AICHI, MIE, SHIGA, KYOTO, OSAKA, HYOGO, NARA, WAKAYAMA, TOTTORI,
//   SHIMANE, OKAYAMA, HIROSHIMA, YAMAGUCHI, TOKUSHIMA, KAGAWA, EHIME, KOCHI,
//   FUKUOKA, SAGA, NAGASAKI, KUMAMOTO, OITA, MIYAZAKI, KAGOSHIMA, OKINAWA
```

```dart
// set the prefecture as "Tokyo"
await Repro.setUserResidencePrefecture(UserProfilePrefecture.tokyo);

// Possible values are as follows:
//   hokkaido, aomori, iwate, miyagi, akita, yamagata,
//   fukushima, ibaraki, tochigi, gunma, saitama, chiba, tokyo, kanagawa,
//   niigata, toyama, ishikawa, fukui, yamanashi, nagano, gifu, shizuoka,
//   aichi, mie, shiga, kyoto, osaka, hyogo, nara, wakayama, tottori,
//   shimane, okayama, hiroshima, yamaguchi, tokushima, kagawa, ehime, kochi,
//   fukuoka, saga, nagasaki, kumamoto, oita, miyazaki, kagoshima, okinawa
```

プッシュ通知やアプリ内メッセージのフィルターを設定する際は、 `東京都` や `大阪府` などのように都道府県名を文字列で指定してください。

#### 生年月日

ユーザーの生年月日をセットします。

```objc
NSDate *date = ... // Create an NSDate object for the user's birthday date
[Repro setUserDateOfBirth:date];
```

```swift
let date = ... // Create an NSDate object for the user's birthday date
Repro.setUserProfile(dateOfBirth: date)
```

```java
Date date = ... // Create a Date object for the user's birthday date
Repro.setUserDateOfBirth(date);
```

```kotlin
val date = ... // Create a Date object for the user's birthday date
Repro.setUserDateOfBirth(date)
```

```cpp
ReproCpp::setUserDateOfBirth(2000, 12, 31);
```

```csharp
DateTime date = ... // Create a DateTime object for the user's birthday date
Repro.SetUserDateOfBirth(date);
```

```js-cordova
let date = ... // Create a Date object for the user's birthday date
Repro.setUserDateOfBirth(date);
```

```js-react-native
let date = ... // Create a Date object for the user's birthday date
Repro.setUserDateOfBirth(date);
```

```js-webview
let date = ... // Create a Date object for the user's birthday date
repro.setUserDateOfBirth(date.getTime());
```

```js-inapp
let date = ... // Create a Date object for the user's birthday date
Repro.setUserDateOfBirth(date.getTime());
```

```dart
DateTime date = ... // Create a DateTime object for the user's birthday date
await Repro.SetUserDateOfBirth(date);
```

#### 年齢

ユーザーの年齢をセットします。

```objc
[Repro setUserAge:20];
```

```swift
Repro.setUserProfile(age: 20)
```

```java
Repro.setUserAge(20);
```

```kotlin
Repro.setUserAge(20)
```

```cpp
ReproCpp::setUserAge(20);
```

```csharp
Repro.SetUserAge(20);
```

```js-cordova
Repro.setUserAge(20);
```

```js-react-native
Repro.setUserAge(20);
```

```js-webview
repro.setUserAge(20);
```

```js-inapp
Repro.setUserAge(20);
```

```dart
await Repro.setUserAge(20);
```

### 自動でセットされる標準ユーザープロフィール

以下の標準ユーザープロフィールは、セッションが発生するたびに自動でセットされるため、APIを呼び出す必要はありません。

#### 最後に使った日

ユーザーが最後にアプリを利用した日付がセットされます。

#### ロケール

ユーザーの端末に設定されているロケールが文字列としてセットされます。IETF言語タグの書式に則り、 `language-script-region` のフォーマットで値がセットされます。IETF言語タグについては [こちらの記事](https://ja.wikipedia.org/wiki/IETF言語タグ) を参考にしてください。

##### NOTE
- 端末ロケールの値は機種に依存するため、同じロケールでも値は複数の可能性があります。例えば、同じ日本語ロケールでも値が `ja` と `ja-JP` のパターンがあります。
- そのため、配信フィルターで設定する際は、 `含む` 条件を利用してください。例えば、前述のように日本語ロケールを指定する場合は、「 `ja` を `含む` 」で配信フィルターを設定してください。

#### ランダムバケットID

ユーザーをランダムかつ均一に分布させたセグメントを作成できるユーザー属性情報です。セグメントに利用することでReproツールの導入検証を容易に行うことができます。
Repro上でユーザーが同定されたタイミングで一度だけランダムに生成され、以降変更されることはありません。値の範囲は0から9999までの整数です。
詳しくは [こちらの記事](https://support.repro.io/hc/ja/articles/53138250139929) を参考にしてください。

ユーザー同定については [ユーザーの定義](https://docs.repro.io/ja/dashboard/misc/user-definition.md) をご確認ください。

#### タイムゾーン

ユーザーの端末に設定されているタイムゾーンが文字列としてセットされます。設定される文字列は、Time Zone Databaseの命名規則に従います。例えば、日本標準時（JST）の場合は `Asia/Tokyo` でセットされます。Time Zone Databaseについては [こちらの記事](https://ja.wikipedia.org/wiki/Tz_database) を参考にしてください。



### カスタムユーザープロフィール

標準ユーザープロフィールとして定義されているもの以外の、サービス独自のプロフィールをセットします。プロフィールのキーには文字列のみが指定できます。 `___repro___` から始まるキーは指定できません。nilや空文字列は不可、上限は255文字です。

またプロフィールの値には、文字列、整数、小数、日付を指定できます。



#### 文字列

セットできる文字数の上限は255文字です。

```objc
[Repro setStringUserProfile:@"Developer" forKey:@"Job"];
```

```swift
Repro.setUserProfile(stringValue: "Developer", forKey: "Job")
```

```java
Repro.setStringUserProfile("Job", "Developer");
```

```kotlin
Repro.setStringUserProfile("Job", "Developer")
```

```cpp
ReproCpp::setStringUserProfile("Job", "Developer");
```

```csharp
Repro.SetStringUserProfile ("Job", "Developer");
```

```js-cordova
Repro.setStringUserProfile("Job", "Developer");
```

```js-react-native
Repro.setStringUserProfile("Job", "Developer");
```

```js-webview
repro.setStringUserProfile("Job", "Developer");
```

```js-inapp
Repro.setStringUserProfile("Job", "Developer");
```

```dart
await Repro.setStringUserProfile("Job", "Developer");
```



#### 整数

```objc
[Repro setIntUserProfile:25 forKey:@"Age"];
```

```swift
Repro.setUserProfile(integerValue: 25, forKey: "age")
```

```java
Repro.setIntUserProfile("Age", 25);
```

```kotlin
Repro.setIntUserProfile("Age", 25)
```

```cpp
ReproCpp::setIntUserProfile("Age", 25);
```

```csharp
Repro.SetIntUserProfile ("Age", 25);
```

```js-cordova
Repro.setIntUserProfile("Age", 25);
```

```js-react-native
Repro.setIntUserProfile("Age", 25);
```

```js-webview
repro.setIntUserProfile("Age", 25);
```

```js-inapp
Repro.setIntUserProfile("Age", 25);
```

```dart
await Repro.setIntUserProfile("Age", 25);
```



#### 小数

```objc
[Repro setDoubleUserProfile:176.5 forKey:@"Height"];
```

```swift
Repro.setUserProfile(doubleValue: 176.5, forKey: "Height")
```

```java
Repro.setDoubleUserProfile("Height", 176.5);
```

```kotlin
Repro.setDoubleUserProfile("Height", 176.5)
```

```cpp
ReproCpp::setDoubleUserProfile("Height", 176.5);
```

```csharp
Repro.SetDoubleUserProfile ("Height", 176.5);
```

```js-cordova
Repro.setDoubleUserProfile("Height", 176.5);
```

```js-react-native
Repro.setDoubleUserProfile("Height", 176.5);
```

```js-webview
repro.setDoubleUserProfile("Height", 176.5);
```

```js-inapp
Repro.setDoubleUserProfile("Height", 176.5);
```

```dart
await Repro.setDoubleUserProfile("Height", 176.5);
```



#### 日付

```objc
NSDate* now = [[NSDate alloc] init];
[Repro setDateUserProfile:now forKey:@"LastLogin"];
```

```swift
let now = Date()
Repro.setUserProfile(dateValue: now, forKey: "LastLogin")
```

```java
Date now = new Date();
Repro.setDateUserProfile("LastLogin", now);
```

```kotlin
val now = Date()
Repro.setDateUserProfile("LastLogin", now)
```

```cpp
std::time_t now = std::time(0);
ReproCpp::setDateUserProfile("LastLogin", now);
```

```csharp
DateTime now = DateTime.Now;
Repro.SetDateUserProfile ("LastLogin", now);
```

```js-cordova
let now = new Date();
Repro.setDateUserProfile("LastLogin", now);
```

```js-react-native
let now = new Date();
Repro.setDateUserProfile("LastLogin", now.toISOString());
```

```js-webview
let now = new Date();
repro.setDateUserProfile("LastLogin", now.getTime());
```

```js-inapp
let now = new Date();
Repro.setDateUserProfile("LastLogin", now.getTime());
```

```dart
final now = DateTime.now();
await Repro.setDateUserProfile("LastLogin", now);
```



### 条件付きセット操作

既にプロフィールが設定されている場合は更新せず、未設定の場合のみ値をセットします。

#### 文字列（条件付き）

指定したキーにプロフィールが未設定の場合のみ、文字列をセットします。

```objc
[Repro onlySetIfAbsentStringUserProfile:@"Developer" forKey:@"Job"];
```

```swift
Repro.onlySetIfAbsentUserProfile(stringValue: "Developer", forKey: "Job")
```

```java
Repro.onlySetIfAbsentStringUserProfile("Job", "Developer");
```

```kotlin
Repro.onlySetIfAbsentStringUserProfile("Job", "Developer")
```

```cpp
ReproCpp::onlySetIfAbsentStringUserProfile("Job", "Developer");
```

```csharp
Repro.OnlySetIfAbsentStringUserProfile ("Job", "Developer");
```

```js-cordova
Repro.onlySetIfAbsentStringUserProfile("Job", "Developer");
```

```js-react-native
Repro.onlySetIfAbsentStringUserProfile("Job", "Developer");
```

```js-webview
repro.onlySetIfAbsentStringUserProfile("Job", "Developer");
```

```js-inapp
Repro.onlySetIfAbsentStringUserProfile("Job", "Developer");
```

```dart
await Repro.onlySetIfAbsentStringUserProfile("Job", "Developer");
```

#### 整数（条件付き）

指定したキーにプロフィールが未設定の場合のみ、整数をセットします。

```objc
[Repro onlySetIfAbsentIntUserProfile:1 forKey: @"LoginCount"];
```

```swift
Repro.onlySetIfAbsentUserProfile(integerValue: 1, forKey: "LoginCount")
```

```java
Repro.onlySetIfAbsentIntUserProfile("LoginCount", 1);
```

```kotlin
Repro.onlySetIfAbsentIntUserProfile("LoginCount", 1)
```

```cpp
ReproCpp::onlySetIfAbsentIntUserProfile("LoginCount", 1);
```

```csharp
Repro.OnlySetIfAbsentIntUserProfile("LoginCount", 1);
```

```js-cordova
Repro.onlySetIfAbsentIntUserProfile("LoginCount", 1);
```

```js-react-native
Repro.onlySetIfAbsentIntUserProfile("LoginCount", 1);
```

```js-webview
repro.onlySetIfAbsentIntUserProfile("LoginCount", 1);
```

```js-inapp
Repro.onlySetIfAbsentIntUserProfile("LoginCount", 1);
```

```dart
await Repro.onlySetIfAbsentIntUserProfile("LoginCount", 1);
```

#### 小数（条件付き）

指定したキーにプロフィールが未設定の場合のみ、小数をセットします。

```objc
[Repro onlySetIfAbsentDoubleUserProfile:85.5 forKey: @"Score"];
```

```swift
Repro.onlySetIfAbsentUserProfile(doubleValue: 85.5, forKey: "Score")
```

```java
Repro.onlySetIfAbsentDoubleUserProfile("Score", 85.5);
```

```kotlin
Repro.onlySetIfAbsentDoubleUserProfile("Score", 85.5)
```

```cpp
ReproCpp::onlySetIfAbsentDoubleUserProfile("Score", 85.5);
```

```csharp
Repro.OnlySetIfAbsentDoubleUserProfile("Score", 85.5);
```

```js-cordova
Repro.onlySetIfAbsentDoubleUserProfile("Score", 85.5);
```

```js-react-native
Repro.onlySetIfAbsentDoubleUserProfile("Score", 85.5);
```

```js-webview
repro.onlySetIfAbsentDoubleUserProfile("Score", 85.5);
```

```js-inapp
Repro.onlySetIfAbsentDoubleUserProfile("Score", 85.5);
```

```dart
await Repro.onlySetIfAbsentDoubleUserProfile("Score", 85.5);
```

#### 日付（条件付き）

指定したキーにプロフィールが未設定の場合のみ、日付をセットします。

```objc
NSDate* now = [[NSDate alloc] init];
[Repro onlySetIfAbsentDateUserProfile:now forKey:@"FirstLogin"];
```

```swift
let now = Date()
Repro.onlySetIfAbsentUserProfile(dateValue: now, forKey: "FirstLogin")
```

```java
Date now = new Date();
Repro.onlySetIfAbsentDateUserProfile("FirstLogin", now);
```

```kotlin
val now = Date()
Repro.onlySetIfAbsentDateUserProfile("FirstLogin", now)
```

```cpp
std::time_t now = std::time(0);
ReproCpp::onlySetIfAbsentDateUserProfile("FirstLogin", now);
```

```csharp
DateTime now = DateTime.Now;
Repro.OnlySetIfAbsentDateUserProfile("FirstLogin", now);
```

```js-cordova
let now = new Date();
Repro.onlySetIfAbsentDateUserProfile("FirstLogin", now);
```

```js-react-native
let now = new Date();
Repro.onlySetIfAbsentDateUserProfile("FirstLogin", now.toISOString());
```

```js-webview
let now = new Date();
repro.onlySetIfAbsentDateUserProfile("FirstLogin", now.getTime());
```

```js-inapp
let now = new Date();
Repro.onlySetIfAbsentDateUserProfile("FirstLogin", now.getTime());
```

```dart
final now = DateTime.now();
await Repro.onlySetIfAbsentDateUserProfile("FirstLogin", now);
```



### 増減操作

既存の数値プロフィールに対して加算・減算を行います。プロフィールが未設定の場合は初期値を0として計算されます。

#### 整数の増加

指定したキーの整数プロフィールに値を加算します。

```objc
[Repro incrementIntUserProfileBy:1 forKey: @"LoginCount"];
```

```swift
Repro.incrementIntegerUserProfile(by: 1, forKey: "LoginCount")
```

```java
Repro.incrementIntUserProfileBy("LoginCount", 1);
```

```kotlin
Repro.incrementIntUserProfileBy("LoginCount", 1)
```

```cpp
ReproCpp::incrementIntUserProfileBy("LoginCount", 1);
```

```csharp
Repro.IncrementIntUserProfileBy("LoginCount", 1);
```

```js-cordova
Repro.incrementIntUserProfileBy("LoginCount", 1);
```

```js-react-native
Repro.incrementIntUserProfileBy("LoginCount", 1);
```

```js-webview
repro.incrementIntUserProfileBy("LoginCount", 1);
```

```js-inapp
Repro.incrementIntUserProfileBy("LoginCount", 1);
```

```dart
await Repro.incrementIntUserProfileBy("LoginCount", 1);
```

#### 整数の減少

指定したキーの整数プロフィールから値を減算します。

```objc
[Repro decrementIntUserProfileBy:10 forKey: @"Credits"];
```

```swift
Repro.decrementIntegerUserProfile(by: 10, forKey: "Credits")
```

```java
Repro.decrementIntUserProfileBy("Credits", 10);
```

```kotlin
Repro.decrementIntUserProfileBy("Credits", 10)
```

```cpp
ReproCpp::decrementIntUserProfileBy("Credits", 10);
```

```csharp
Repro.DecrementIntUserProfileBy("Credits", 10);
```

```js-cordova
Repro.decrementIntUserProfileBy("Credits", 10);
```

```js-react-native
Repro.decrementIntUserProfileBy("Credits", 10);
```

```js-webview
repro.decrementIntUserProfileBy("Credits", 10);
```

```js-inapp
Repro.decrementIntUserProfileBy("Credits", 10);
```

```dart
await Repro.decrementIntUserProfileBy("Credits", 10);
```

#### 小数の増加

指定したキーの小数プロフィールに値を加算します。

```objc
[Repro incrementDoubleUserProfileBy:5.5 forKey: @"Score"];
```

```swift
Repro.incrementDoubleUserProfile(by: 5.5, forKey: "Score")
```

```java
Repro.incrementDoubleUserProfileBy("Score", 5.5);
```

```kotlin
Repro.incrementDoubleUserProfileBy("Score", 5.5)
```

```cpp
ReproCpp::incrementDoubleUserProfileBy("Score", 5.5);
```

```csharp
Repro.IncrementDoubleUserProfileBy("Score", 5.5);
```

```js-cordova
Repro.incrementDoubleUserProfileBy("Score", 5.5);
```

```js-react-native
Repro.incrementDoubleUserProfileBy("Score", 5.5);
```

```js-webview
repro.incrementDoubleUserProfileBy("Score", 5.5);
```

```js-inapp
Repro.incrementDoubleUserProfileBy("Score", 5.5);
```

```dart
await Repro.incrementDoubleUserProfileBy("Score", 5.5);
```

#### 小数の減少

指定したキーの小数プロフィールから値を減算します。

```objc
[Repro decrementDoubleUserProfileBy:25.0 forKey: @"Balance"];
```

```swift
Repro.decrementDoubleUserProfile(by: 25.0, forKey: "Balance")
```

```java
Repro.decrementDoubleUserProfileBy("Balance", 25.0);
```

```kotlin
Repro.decrementDoubleUserProfileBy("Balance", 25.0)
```

```cpp
ReproCpp::decrementDoubleUserProfileBy("Balance", 25.0);
```

```csharp
Repro.DecrementDoubleUserProfileBy("Balance", 25.0);
```

```js-cordova
Repro.decrementDoubleUserProfileBy("Balance", 25.0);
```

```js-react-native
Repro.decrementDoubleUserProfileBy("Balance", 25.0);
```

```js-webview
repro.decrementDoubleUserProfileBy("Balance", 25.0);
```

```js-inapp
Repro.decrementDoubleUserProfileBy("Balance", 25.0);
```

```dart
await Repro.decrementDoubleUserProfileBy("Balance", 25.0);
```

### 標準ユーザープロフィールの条件付きセット・増減操作

標準ユーザープロフィールに対しても条件付きセットや増減操作が利用できます。

#### 年齢（条件付き）

年齢が未設定の場合のみ値をセットします。

```objc
[Repro onlySetIfAbsentUserAge:25];
```

```swift
Repro.onlySetIfAbsentUserProfile(age: 25)
```

```java
Repro.onlySetIfAbsentUserAge(25);
```

```kotlin
Repro.onlySetIfAbsentUserAge(25)
```

```cpp
ReproCpp::onlySetIfAbsentUserAge(25);
```

```csharp
Repro.OnlySetIfAbsentUserAge(25);
```

```js-cordova
Repro.onlySetIfAbsentUserAge(25);
```

```js-react-native
Repro.onlySetIfAbsentUserAge(25);
```

```js-webview
repro.onlySetIfAbsentUserAge(25);
```

```js-inapp
Repro.onlySetIfAbsentUserAge(25);
```

```dart
await Repro.onlySetIfAbsentUserAge(25);
```

#### 性別（条件付き）

性別が未設定の場合のみ値をセットします。

```objc
[Repro onlySetIfAbsentUserGender:RPRUserProfileGenderMale];
```

```swift
Repro.onlySetIfAbsentUserProfile(gender: .male)
```

```java
Repro.onlySetIfAbsentUserGender(UserProfileGender.MALE);
```

```kotlin
Repro.onlySetIfAbsentUserGender(UserProfileGender.MALE)
```

```cpp
ReproCpp::onlySetIfAbsentUserGender(ReproCpp::UserProfileGenderMale);
```

```csharp
Repro.OnlySetIfAbsentUserGender(UserProfileGender.Male);
```

```js-cordova
Repro.onlySetIfAbsentUserGender(Repro.UserProfileGender.Male);
```

```js-react-native
Repro.onlySetIfAbsentUserGender(Repro.GENDER_MALE);
```

```js-webview
repro.onlySetIfAbsentUserGender(repro.userProfileGender.Male);
```

```js-inapp
Repro.onlySetIfAbsentUserGender(Repro.UserProfileGender.Male);
```

```dart
await Repro.onlySetIfAbsentUserGender(UserGender.male);
```

#### Eメールアドレス（条件付き）

Eメールアドレスが未設定の場合のみ値をセットします。

```objc
[Repro onlySetIfAbsentUserEmailAddress:@"user@example.com"];
```

```swift
Repro.onlySetIfAbsentUserProfile(emailAddress: "user@example.com")
```

```java
Repro.onlySetIfAbsentUserEmailAddress("user@example.com");
```

```kotlin
Repro.onlySetIfAbsentUserEmailAddress("user@example.com")
```

```cpp
ReproCpp::onlySetIfAbsentUserEmailAddress("user@example.com");
```

```csharp
Repro.OnlySetIfAbsentUserEmailAddress("user@example.com");
```

```js-cordova
Repro.onlySetIfAbsentUserEmailAddress("user@example.com");
```

```js-react-native
Repro.onlySetIfAbsentUserEmailAddress("user@example.com");
```

```js-webview
repro.onlySetIfAbsentUserEmailAddress("user@example.com");
```

```js-inapp
Repro.onlySetIfAbsentUserEmailAddress("user@example.com");
```

```dart
await Repro.onlySetIfAbsentUserEmailAddress("user@example.com");
```

#### 居住都道府県（条件付き）

居住都道府県が未設定の場合のみ値をセットします。

```objc
// set the prefecture as "Tokyo"
[Repro onlySetIfAbsentUserResidencePrefecture:RPRUserProfilePrefectureTokyo];
```

```swift
// set the prefecture as "Tokyo"
Repro.onlySetIfAbsentUserProfile(residencePrefecture: .tokyo)
```

```java
// set the prefecture as "Tokyo"
Repro.onlySetIfAbsentUserResidencePrefecture(UserProfilePrefecture.TOKYO);
```

```kotlin
// set the prefecture as "Tokyo"
Repro.onlySetIfAbsentUserResidencePrefecture(UserProfilePrefecture.TOKYO)
```

```cpp
// set the prefecture as "Tokyo"
ReproCpp::onlySetIfAbsentUserResidencePrefecture(ReproCpp::UserProfilePrefectureTokyo);
```

```csharp
// set the prefecture as "Tokyo"
Repro.OnlySetIfAbsentUserResidencePrefecture(UserProfilePrefecture.Tokyo);
```

```js-cordova
// set the prefecture as "Tokyo"
Repro.onlySetIfAbsentUserResidencePrefecture(Repro.UserProfilePrefecture.Tokyo);
```

```js-react-native
// set the prefecture as "Tokyo"
Repro.onlySetIfAbsentUserResidencePrefecture(Repro.PREFECTURE_TOKYO);
```

```js-webview
// set the prefecture as "Tokyo"
repro.onlySetIfAbsentUserResidencePrefecture(repro.userProfilePrefecture.TOKYO);
```

```js-inapp
// set the prefecture as "Tokyo"
Repro.onlySetIfAbsentUserResidencePrefecture(Repro.UserProfilePrefecture.TOKYO);
```

```dart
// set the prefecture as "Tokyo"
await Repro.onlySetIfAbsentUserResidencePrefecture(UserProfilePrefecture.tokyo);
```

#### 生年月日（条件付き）

生年月日が未設定の場合のみ値をセットします。

```objc
NSDate *date = ... // Create an NSDate object for the user's birthday date
[Repro onlySetIfAbsentUserDateOfBirth:date];
```

```swift
let date = ... // Create an NSDate object for the user's birthday date
Repro.onlySetIfAbsentUserProfile(dateOfBirth: date)
```

```java
Date date = ... // Create a Date object for the user's birthday date
Repro.onlySetIfAbsentUserDateOfBirth(date);
```

```kotlin
val date = ... // Create a Date object for the user's birthday date
Repro.onlySetIfAbsentUserDateOfBirth(date)
```

```cpp
ReproCpp::onlySetIfAbsentUserDateOfBirth(2000, 12, 31);
```

```csharp
DateTime date = ... // Create a DateTime object for the user's birthday date
Repro.OnlySetIfAbsentUserDateOfBirth(date);
```

```js-cordova
let date = ... // Create a Date object for the user's birthday date
Repro.onlySetIfAbsentUserDateOfBirth(date);
```

```js-react-native
let date = ... // Create a Date object for the user's birthday date
Repro.onlySetIfAbsentUserDateOfBirth(date);
```

```js-webview
let date = ... // Create a Date object for the user's birthday date
repro.onlySetIfAbsentUserDateOfBirth(date.getTime());
```

```js-inapp
let date = ... // Create a Date object for the user's birthday date
Repro.onlySetIfAbsentUserDateOfBirth(date.getTime());
```

```dart
DateTime date = ... // Create a DateTime object for the user's birthday date
await Repro.onlySetIfAbsentUserDateOfBirth(date);
```

#### 年齢の増加

現在の年齢に指定した値を加算します。

```objc
[Repro incrementUserAgeBy:1];
```

```swift
Repro.incrementUserProfileAge(by: 1)
```

```java
Repro.incrementUserAgeBy(1);
```

```kotlin
Repro.incrementUserAgeBy(1)
```

```cpp
ReproCpp::incrementUserAgeBy(1);
```

```csharp
Repro.IncrementUserAgeBy(1);
```

```js-cordova
Repro.incrementUserAgeBy(1);
```

```js-react-native
Repro.incrementUserAgeBy(1);
```

```js-webview
repro.incrementUserAgeBy(1);
```

```js-inapp
Repro.incrementUserAgeBy(1);
```

```dart
await Repro.incrementUserAgeBy(1);
```

#### 年齢の減少

現在の年齢から指定した値を減算します。

```objc
[Repro decrementUserAgeBy:1];
```

```swift
Repro.decrementUserProfileAge(by: 1)
```

```java
Repro.decrementUserAgeBy(1);
```

```kotlin
Repro.decrementUserAgeBy(1)
```

```cpp
ReproCpp::decrementUserAgeBy(1);
```

```csharp
Repro.DecrementUserAgeBy(1);
```

```js-cordova
Repro.decrementUserAgeBy(1);
```

```js-react-native
Repro.decrementUserAgeBy(1);
```

```js-webview
repro.decrementUserAgeBy(1);
```

```js-inapp
Repro.decrementUserAgeBy(1);
```

```dart
await Repro.decrementUserAgeBy(1);
```

### ユーザープロフィールの削除

設定済みのユーザープロフィールを削除します。

#### カスタムプロフィールの削除

指定したキーのカスタムユーザープロフィールを削除します。

```objc
[Repro deleteUserProfile:@"Job"];
```

```swift
Repro.deleteUserProfile(forKey: "Job")
```

```java
Repro.deleteUserProfile("Job");
```

```kotlin
Repro.deleteUserProfile("Job")
```

```cpp
ReproCpp::deleteUserProfile("Job");
```

```csharp
Repro.DeleteUserProfile("Job");
```

```js-cordova
Repro.deleteUserProfile("Job");
```

```js-react-native
Repro.deleteUserProfile("Job");
```

```js-webview
repro.deleteUserProfile("Job");
```

```js-inapp
Repro.deleteUserProfile("Job");
```

```dart
await Repro.deleteUserProfile("Job");
```

#### 標準プロフィールの削除

標準ユーザープロフィールを削除します。

性別の削除:

```objc
[Repro deleteUserGender];
```

```swift
Repro.deleteUserProfileGender()
```

```java
Repro.deleteUserGender();
```

```kotlin
Repro.deleteUserGender()
```

```cpp
ReproCpp::deleteUserGender();
```

```csharp
Repro.DeleteUserGender();
```

```js-cordova
Repro.deleteUserGender();
```

```js-react-native
Repro.deleteUserGender();
```

```js-webview
repro.deleteUserGender();
```

```js-inapp
Repro.deleteUserGender();
```

```dart
await Repro.deleteUserGender();
```

年齢の削除:

```objc
[Repro deleteUserAge];
```

```swift
Repro.deleteUserProfileAge()
```

```java
Repro.deleteUserAge();
```

```kotlin
Repro.deleteUserAge()
```

```cpp
ReproCpp::deleteUserAge();
```

```csharp
Repro.DeleteUserAge();
```

```js-cordova
Repro.deleteUserAge();
```

```js-react-native
Repro.deleteUserAge();
```

```js-webview
repro.deleteUserAge();
```

```js-inapp
Repro.deleteUserAge();
```

```dart
await Repro.deleteUserAge();
```

Eメールアドレスの削除:

```objc
[Repro deleteUserEmailAddress];
```

```swift
Repro.deleteUserProfileEmailAddress()
```

```java
Repro.deleteUserEmailAddress();
```

```kotlin
Repro.deleteUserEmailAddress()
```

```cpp
ReproCpp::deleteUserEmailAddress();
```

```csharp
Repro.DeleteUserEmailAddress();
```

```js-cordova
Repro.deleteUserEmailAddress();
```

```js-react-native
Repro.deleteUserEmailAddress();
```

```js-webview
repro.deleteUserEmailAddress();
```

```js-inapp
Repro.deleteUserEmailAddress();
```

```dart
await Repro.deleteUserEmailAddress();
```

居住都道府県の削除:

```objc
[Repro deleteUserResidencePrefecture];
```

```swift
Repro.deleteUserProfileResidencePrefecture()
```

```java
Repro.deleteUserResidencePrefecture();
```

```kotlin
Repro.deleteUserResidencePrefecture()
```

```cpp
ReproCpp::deleteUserResidencePrefecture();
```

```csharp
Repro.DeleteUserResidencePrefecture();
```

```js-cordova
Repro.deleteUserResidencePrefecture();
```

```js-react-native
Repro.deleteUserResidencePrefecture();
```

```js-webview
repro.deleteUserResidencePrefecture();
```

```js-inapp
Repro.deleteUserResidencePrefecture();
```

```dart
await Repro.deleteUserResidencePrefecture();
```

生年月日の削除:

```objc
[Repro deleteUserDateOfBirth];
```

```swift
Repro.deleteUserProfileDateOfBirth()
```

```java
Repro.deleteUserDateOfBirth();
```

```kotlin
Repro.deleteUserDateOfBirth()
```

```cpp
ReproCpp::deleteUserDateOfBirth();
```

```csharp
Repro.DeleteUserDateOfBirth();
```

```js-cordova
Repro.deleteUserDateOfBirth();
```

```js-react-native
Repro.deleteUserDateOfBirth();
```

```js-webview
repro.deleteUserDateOfBirth();
```

```js-inapp
Repro.deleteUserDateOfBirth();
```

```dart
await Repro.deleteUserDateOfBirth();
```

---

## ユーザーID

アプリケーションの固有のユーザーIDを設定できます。ユーザーIDを設定すると、エンドユーザーが複数の端末やブラウザを使っている場合に、異なる端末やブラウザから上がってくるセッション情報を同一ユーザーのものとみなすことができるようになります。

セットするのは、以下のようなユーザーを一意に特定できる文字列です。

- サービスで使用している会員ID

##### WARNING
デバイスに対して1度設定したユーザーIDの値と異なる値を送信すると、当該デバイスへ最後にセットされたユーザーIDと当該デバイスが紐付き、過去に紐付いていたユーザーは当該デバイスとの紐付きが解消されます。

1度ユーザーIDを設定すると、異なる値が再度設定されたタイミングより別のユーザーの行動履歴としてみなされるため、 **ユーザーIDとして設定する値の定義は慎重に検討してください** 。



### ユーザーIDをセットする

##### WARNING
以下のような値は、ユーザーIDとして推奨しません。

- **氏名のような重複する可能性のある文字列**
   
  異なるユーザーが利用した場合であっても、同じ値であれば、同一ユーザーが複数のデバイスやブラウザを利用しているとみなされます
   
- **メールアドレスや電話番号のようなユーザーが任意で変更可能な文字列**
   
  セットするユーザーIDが変更された場合、異なる値であれば別のユーザーが端末やブラウザを利用しているという扱いになります
   
  また、セキュリティ観点でも暗号化などを行うことが推奨されます
   

あわせて｢[ユーザーIDを考える](https://support.repro.io/hc/ja/articles/900005686063)｣も参考にしてください。

ユーザーIDをセットします。文字数の上限は191文字です。

ユーザーIDには、null・空文字および空白のみで構成された文字列を除き、任意の文字や記号を登録可能です。また、大文字・小文字は区別されます（例: "aaa" と "AAA" は別ユーザーとして扱われます）。

```objc
[Repro setUserID:@"xxxxxxxxxxxx"];
```

```swift
Repro.set(userID: "xxxxxxxxxxxx")
```

```java
Repro.setUserID("xxxxxxxxxxxx");
```

```kotlin
Repro.setUserID("xxxxxxxxxxxx")
```

```cpp
ReproCpp::setUserID("xxxxxxxxxxxx");
```

```csharp
Repro.SetUserID ("xxxxxxxxxxxx");
```

```js-cordova
Repro.setUserID("xxxxxxxxxxxx");
```

```js-react-native
Repro.setUserID("xxxxxxxxxxxx");
```

```dart
await Repro.setUserID("xxxxxxxxxxxx");
```

アプリ内において、ユーザーを一意に特定することが不可能な場合は、代替手段として [デバイスID](https://docs.repro.io/ja/dev/sdk/device-id.html) をユーザーIDとしてセットすることも可能です。

##### NOTE
ログイン機能がある場合、未ログインの状態で、ユーザーIDをセットしないようにしてください。ユーザーIDがセットされていない状態で記録された行動履歴・ユーザープロフィールは、ユーザーIDをセットした後も引き継がれますが、ログイン前にユーザーIDを明示的に指定してしまった場合、ログイン前とログイン後の行動履歴・ユーザープロフィールが別のユーザーのものとして取り扱われてしまいます。

詳しくは｢[ユーザーIDを設定するタイミングのベストプラクティスを教えて下さい](https://support.repro.io/hc/ja/articles/900004746426)｣で解説します。



### ユーザーIDを取得する

セットしたユーザーIDを取得します。

```objc
NSString* userID = [Repro getUserID];
```

```swift
let userID = Repro.userID()
```

```java
String userID = Repro.getUserID();
```

```kotlin
val userID = Repro.getUserID()
```

```cpp
const char* userID = ReproCpp::getUserID();
```

```csharp
string userID = Repro.GetUserID ();
```

```js-cordova
// retrieve userID via callback function
Repro.getUserID(function(userID) {
  ...
});
```

```js-react-native
// retrieve userID via callback function
Repro.getUserID((error, userID) => {
  ...
});
```

```dart
final userId = await Repro.getUserID();
```

---

## フィルターを追加

### ユーザーフィルターを追加

[リテンション分析](https://docs.repro.io/ja/dashboard/analytics/retention-analysis.md)、
[アクセス分析](https://docs.repro.io/ja/dashboard/analytics/access-summary.md)、
[KPI分析](https://docs.repro.io/ja/dashboard/analytics/kpi-analysis.md)、
[ファネル分析](https://docs.repro.io/ja/dashboard/analytics/funnel-analysis.md) の各アナリティクス画面では、ユーザープロフィールの値でフィルターを追加できます。
例えば、表示されているデータをさらに性別や年代でフィルタリングし、分析できます。
ユーザープロフィールに関する詳細は [ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md) をご覧ください。

#### 設定手順



各アナリティクス画面の右上にある、 **フィルターを追加** ボタンをクリックすると、登録されているユーザープロフィールが表示されます。


1. 左側のユーザープロフィール一覧から、指定したいユーザープロフィールを選択します
2. 右側のフォームに指定したユーザープロフィールの値を入力します
3. **適用** ボタンをクリックするとフィルタリングが適用されます

※ この例ではユーザープロフィールの **性別** に **female** がセットされているデータをフィルタリングします。

##### NOTE
- ユーザープロフィールは左上の検索フォームから検索できます。
- 登録されている値のサンプルは最大10件まで表示されます。 サンプルはクリックすると、フォームに反映されます。
- 登録されている値のサンプルはサンプルのため、セットされている値が必ず表示されるとは限りません。
- フィルタリングの適用には1分程度の時間がかかる場合があります。
- フィルタリングを適用した場合、アクセス分析で「全アクセス」が選択できなくなります。

### プラットフォームの絞り込み

[リテンション分析](https://docs.repro.io/ja/dashboard/analytics/retention-analysis.md)、
[アクセス分析](https://docs.repro.io/ja/dashboard/analytics/access-summary.md)、
[KPI分析](https://docs.repro.io/ja/dashboard/analytics/kpi-analysis.md)、
[ファネル分析](https://docs.repro.io/ja/dashboard/analytics/funnel-analysis.md) の各アナリティクス画面では、プラットフォーム毎の集計結果を絞り込むことができます。
例えば、表示されているデータをさらにAndroidやiOSでフィルタリングし、分析できます。

#### 設定手順



各アナリティクス画面の右上にある、 **プラットフォーム** ボタンをクリックすると、各プラットフォームを選択できます。


1. **プラットフォーム** ボタンをクリック
2. **iOS** をクリック

※ この例ではプラットフォームが **iOS** のみの集計結果が表示されます。

##### NOTE
- **プラットフォーム** は **iOS** 、 **Android** 、 **Web** があります。
- **プラットフォーム** と表示されている場合はフィルターが掛っていない状態となります。
- ご利用されているプラットフォームに関わらず、 **プラットフォーム** は **iOS** 、 **Android** 、 **Web** が表示されます。
- ご利用されていないプラットフォームでの表示結果はすべて0になります。

---

## リテンション分析

リテンション分析は、どれぐらいのユーザーがアプリやWebサイトを利用し続けているのか、一目で確認する分析手法です。Reproのリテンション分析では、継続率の把握に加え、イベントと継続率の相関分析を行うことができます。

##### NOTE
リテンション分析を利用するにはイベントトラッキングの設定が必要です。詳細は [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md) をご覧ください。

|  | **事例: Twitter** Twitterは、リテンション分析によってユーザー行動を把握し、新規ユーザーが登録した際に6人以上ユーザーをフォローすることを勧めることによって、再訪率の向上を実現しました。 |
| --- | --- |

### リテンション分析画面

[アナリティクス] > [リテンション分析]をクリックし、リテンション分析画面を表示します。



#### フィルタ設定



| 項目 | 説明 |
| --- | --- |
| プラットフォーム | プラットフォームを「iOS/Android/Web」から選択できます。選択したプラットフォームごとの結果が表示されます。 |
| フィルター | 性別やメールアドレスなど、ユーザープロフィールの条件でフィルタリングできます。 |
| 期間 | 分析する期間を設定します。「開始日と終了日を指定」の場合、期間は25ヶ月前まで選択できます。 |
| 日/週/月 | 期間を日、週、月、指定に分けて集計します。 |

#### イベント設定

イベントの発生回数を基にしたリテンションの確認ができます。

以下は、直近7日間に商品詳細ページに1回以上アクセスした全てのユーザーの分析結果を表示する例です。



#### CSV出力

分析データをCSVでダウンロードできます。

出力したいデータを表示し、CSVダウンロードボタンをクリックしてください。



#### グラフ

- Y軸は、分析設定した条件に合致するユーザー数を日毎に示します。
- X軸は、Y軸に示されたユーザーが再訪するのにかかった日数を示します。

以下の例では、 3/22 に 62 人のユーザーが「アプリ起動」を実行し、 5 日後に 33.87% のユーザーが再訪したことを示しています。



**例**

Eコマースサービスを例に説明すると、ユーザーが商品ページを閲覧したときにトラックした「商品詳細」イベントを実行したあとの継続率を表示するようにリテンション分析を設定することができます。

例えば、同じイベントを2回実行したユーザーと3回実行したユーザーとでその後の再訪率を比較することで、ユーザーの再訪率を上げるために最適なイベントの実行回数を分析することができます。

---

## アクセス分析

アクセス分析では、アプリやWebサイトの利用状況をひとめで確認し、どういう機能がよく使われているか、ユーザーに期待する行動が実際に行われているかどうかを把握することができます。

アクセス分析では、アプリの起動回数に加え、以下のような統計情報も閲覧することが可能です。

- イベント別の実行回数
- DAU/MAU（デイリーアクティブユーザー・マンスリーアクティブユーザー）

アクセス分析にはイベントトラッキングが必要です。詳細は [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md) をご覧ください。

### アクセス分析画面

[アナリティクス] > [アクセス分析]をクリックし、アクセス分析画面を表示します。



#### フィルタ設定



| 項目 | 説明 |
| --- | --- |
| プラットフォーム | プラットフォームを「iOS/Android/Web」から選択できます。選択したプラットフォームごとの結果が表示されます。 |
| フィルター | 性別やメールアドレスなど、ユーザープロフィールの条件でフィルタリングできます。 |
| 期間 | 分析する期間を設定します。「開始日と終了日を指定」の場合、期間は25ヶ月前まで選択できます。 |
| 日/週/月 | 期間を日、週、月、指定に分けて集計します。 |
| ユーザー | ユーザーを「全ユーザー/新規ユーザー/全アクセス」から選択できます。 |
| イベントを設定 | イベントを選択できます。 |

##### NOTE
「全アクセス」を指定している場合、ユーザーフィルターは設定できません。

#### CSV出力

分析データをCSVでダウンロードできます。

出力したいデータを表示し、CSVダウンロードボタンをクリックしてください。

---

## KPI分析

KPI分析では、商品の購入や記事の投稿など、重要なイベントの達成率から、アプリやWebサイトの課題発見と施策の効果を検証することができます。

KPI分析にはイベントトラッキングが必要です。詳細は [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md) をご覧ください。

---

**例**



上記の例では、1/29 から1/31までに行った変更によって、商品ページを閲覧したユーザーのコンバージョンが下がったことがわかります。

---

**初回ユーザーのKPIを見る**

サービスに加えた変更を検証するために、新規ユーザーを対象としたKPI分析を実施することができます。新しいレイアウトやデザインを試したあとの効果を正確に知るためには、既存のユーザーの数字を除外することが重要なためです。

---

## ファネル分析

ファネル分析では、どこで多くのユーザーが離脱しているのかを一目で確認することができます。

開発時に想定していたユーザーの操作と実際の操作を照らし合わせて問題のあるフローを洗い出すことがファネル分析の目的です。

ファネル分析にはイベントトラッキングが必要です。詳細は [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md) をご覧ください。

---

**例**

Eコマースのサービスを例にとると、「商品一覧」->「商品ページ」->「カートに追加」->「購入」というアクションを実行したユーザー数を知ることができます。また、どれくらいの数のユーザーが途中でドロップしたのかを知ることも重要です。

それらの顧客に対し、購入まで至ってもらうようにキャンペーンを配信することができます。



##### NOTE
* 各ステップに登録されたイベント間を遷移したユーザー数は、単位期間(日/週/月)内にトラックされたイベントの発生順序がステップの順序と合致している場合に計上される様になっております。そのため、各ステップに登録されたイベント間遷移は、当該イベントを連続して実行されたことを保証するものではありません。
* 新規にファネル分析を設定した場合、設定した当日がデータの集計対象になります。そのため、設定日より過去のデータを取得することはできません。詳しくは [新規で作成したファネル分析において、過去分のデータは集計されますか？](https://reproio.zendesk.com/hc/ja/articles/900005691483-%E6%96%B0%E8%A6%8F%E3%81%A7%E4%BD%9C%E6%88%90%E3%81%97%E3%81%9F%E3%83%95%E3%82%A1%E3%83%8D%E3%83%AB%E5%88%86%E6%9E%90%E3%81%AB%E3%81%8A%E3%81%84%E3%81%A6-%E9%81%8E%E5%8E%BB%E5%88%86%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AF%E9%9B%86%E8%A8%88%E3%81%95%E3%82%8C%E3%81%BE%E3%81%99%E3%81%8B-) を参照してください。

---

## オーディエンス

オーディエンスとは、アプリやWebサイト内のイベントまたはユーザープロフィールに基づいてユーザーをフィルタリングし、配信対象ユーザー群として保存できる機能です。保存したオーディエンスは主にプッシュ通知やメッセージといったマーケティング機能で利用することができます。例えば「3日前にアプリを使用して、その後2日間アプリを使っていないユーザー」のオーディエンスを作成し、プッシュ通知やメッセージで利用することでリテンションレートを高めるための施策を推進することができます。

### オーディエンスの種類

以下の3種類のオーディエンスを利用できます。

- [フィルター](#create-filters): イベントやユーザープロフィール、既存ユーザーといったセグメンテーションフィルターを使います。
- [インポート](#create-import): 他のデータを元に用意した [ユーザーID](https://docs.repro.io/ja/dev/sdk/user-id.md) のリストをオーディエンスとして利用します。
- [ID指定](#create-specified-id): ユーザーID、またはデバイスIDを検索してオーディエンスを作成します。

### オーディエンスを作成する

**マーケティング > オーディエンス** を開き、 **新規作成** をクリックします。





#### 新規作成: フィルター



##### オーディエンス名

配信対象ユーザー群に名前をつけて管理します。オーディエンスの一覧に表示され、各マーケティング機能で利用する際の選択肢として表示されます。

##### 配信対象を選択する



イベントやユーザープロフィール、既存ユーザーといったセグメンテーションフィルターをつかって、配信対象となるユーザーを指定できます。各フィルターは **and** 、 **and not** 、 **or** を使って、最大5個まで組み合わせられます。

- **and**: 指定した条件を全て満たすユーザーが対象になります
- **and not**: 指定した条件にあてはまるユーザーが対象から除外されます
- **or**: 指定した複数の条件のどれかにあてはまるユーザーが対象になります

例えば:

- 3日前にアプリを使用して、その後2日間アプリを使っていないユーザーへ配信する場合


- 性別が女性で直近3日以内にイベントAかイベントBのどちらかを実行したユーザーへ配信する場合



###### イベントでフィルタリング

[イベント](https://docs.repro.io/ja/dev/sdk/tracking.md) を実行したユーザーをセグメンテーションすることができます。実行した期間や回数を指定することができます。

###### イベントプロパティでフィルタリング

[イベント](https://docs.repro.io/ja/dev/sdk/tracking.md) を実行したユーザーのうち、実行されたイベントに付帯するプロパティにもとづいてユーザーをセグメンテーションすることができます。プロパティの名前や値、実行した期間や回数を指定することができます。



###### ユーザープロフィールでフィルタリング

[ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md) に登録されている情報にもとづいてユーザーをセグメンテーションすることができます。SDKでプロフィールの型に数値を指定している場合、「以上、以下、より大きい、より小さい」などをつかって、値を比較する条件を指定できます。文字を指定している場合、「一致する、一致しない、含む」などをつかって、条件を指定できます。日付を指定している場合、「◯日前以前、◯日前〜▢日前、特定日以前」などをつかって、条件を指定できます。

日付の指定については、[サポートサイトのFAQ](https://support.repro.io/hc/ja/articles/23886462974489) に詳細な説明がありますので、こちらも参考にしてください。

###### 既存ユーザー

Reproに登録されたすべてのユーザーが対象となります。既存ユーザーから特定条件を満たすユーザーを除外する場合は、 **and not** でフィルターを追加してください。

##### NOTE
- オーディエンスのフィルターには他のオーディエンスを指定することはできません。





#### 新規作成: インポート



##### オーディエンス名

配信対象ユーザー群に名前をつけて管理します。オーディエンスの一覧に表示され、各マーケティング機能で利用する際の選択肢として表示されます。

##### 対象ユーザー

**CSVを選択する** より、お手持ちのファイルを選択します。ファイルの形式は、1行に1つのユーザーIDを指定した以下のようなCSVです。例えば `qwpeoifjadlskf`, `zxocjvasdfoiji`, `azxcpoqnadslpx` のようなユーザーIDを設定している場合、次のような形式のファイルになります。

```
qwpeoifjadlskf
zxocjvasdfoiji
azxcpoqnadslpx
:
```

##### WARNING
- ファイル内に1行でも不正なフォーマットがある場合、対象のCSVファイルの取り込みは一切行われません。
- オーディエンスの取り込みが完了しメールが送信されるまでは、対象のオーディエンスをキャンペーンの配信対象として利用することはできません。また、取り込みが完了していないオーディエンスは、管理画面上に通知バナーで表示されます。

##### NOTE
- ファイル内で指定するユーザーIDは、 [アプリ内やWebサイトから設定されるユーザーID](https://docs.repro.io/ja/dev/sdk/user-id.md#set-app-user-id) をそのまま指定してください。
- CSVのテキストエンコーディングはUTF-8です。
- CSVの最大ファイルサイズは500MB(ユーザーIDが固定長30文字であれば約1700万件)です。
- Reproに登録されているユーザーが対象となります。Reproに登録されていないユーザーが含まれている場合は、対象として計上されません。
- 対象ユーザーの算出は、オーディエンスを利用したキャンペーンの対象ユーザー導出時に行われます。

##### オーディエンスを保存する

設定した内容を確認後、 **オーディエンスを保存** をクリックするとオーディエンスが作成されます。

##### インポート結果のメールを受信する

インポートが完了すると、下記のようなメールが送信されます。
URLにアクセスし、インポート結果を確認してください。





#### 新規作成: ID指定



##### オーディエンス名

配信対象ユーザー群に名前をつけて管理します。オーディエンスの一覧に表示され、各マーケティング機能で利用する際の選択肢として表示されます。



##### QRコードを利用してユーザーを追加する

##### NOTE
- この機能を利用するにはiOS SDKバージョン5.16.0以上、Android SDKバージョン5.15.0以上で且つディープリンクの実装が必要です。 [詳細はこちらのドキュメント](https://docs.repro.io/ja/dev/sdk/qr-code.html) を参照してください。
- SDKバージョンが上記のバージョン未満の場合は、QRコードは表示されません。



ユーザー追加QRコードを読み取ってアプリを起動することでID指定オーディエンスの追加候補として簡単に検索出来ます。
以下の手順に従って追加してください。

###### ユーザー追加QRコードを読み取りアプリを起動

画面上に表示されるQRコードを、ID指定オーディエンスに追加したいユーザーの端末で読み取ります。
アプリ起動時に、QRコードを読み取った時間が「ユーザー追加QRコードを最後に読み取った日」という標準ユーザープロフィールにセットされます。

##### NOTE
- アプリ起動時に、アプリの画面上に特にメッセージは表示されません。
- カメラアプリ等でQRコードを読み取った際 `使用可能なデータが見つかりません` 等のメッセージが表示される場合は以下を確認してください。
  - 端末に入っているアプリに含まれるReproSDKが対応SDKバージョンになっているか
  - ディープリンクの実装がされているか

###### QRコードを読み取ったユーザーを検索

`QRコードを読み取ったユーザーを検索` ボタンをクリックしてQRコードを読み取ったユーザーを検索してください。
その後、検索結果から追加したいユーザーの **+ (登録)** ボタンをクリックしてください。

##### NOTE
- QRコードを読み取ってから、検索出来るようになるまで数分かかる場合があります。
- 検索してもユーザーが表示されない場合はしばらく待ってから再度 `QRコードを読み取ったユーザーを検索` ボタンを押して下さい。

##### IDを指定してユーザーを追加する

**ユーザーを検索** より、追加したいユーザーID、もしくはデバイスIDを入力して検索してください。
その後、検索結果から追加したいユーザーの **+ (登録)** ボタンをクリックしてください。

##### NOTE
- 検索は完全一致したユーザーのみ表示されます。
- 同じユーザーIDが複数のデバイスやブラウザ上でセットされている場合、すべてのデバイスとブラウザが対象となります。
- 1オーディエンスごとに最大50件まで登録できます。

###### 検索に利用する識別子の確認方法

App

- ユーザーID: [ユーザーIDを取得する](https://docs.repro.io/ja/dev/sdk/user-id.md#get-app-user-id)
- デバイスID: [デバイスIDを取得](https://docs.repro.io/ja/dev/sdk/device-id.md#get-app-divice-id)

Web

- ユーザーID: [ユーザーID](https://docs.repro.io/ja/dev/web/user-id.md)
- デバイスID: [デバイスIDを取得](https://docs.repro.io/ja/dev/web/device-id.md#get-web-divice-id)

###### ユーザーが複数表示された場合

この場合は最新のユーザー情報が順に表示されているため、一番上に表示されたユーザーを追加してください。



###### ユーザーが見つからない場合

検索したユーザーがRepro上に存在しない場合は、 `ユーザーが見つかりませんでした。` というエラーメッセージが出力されます。

このメッセージが出力される時に考えられる原因は複数あり、主な原因は下記の通りです。

1. (ユーザーIDで検索した場合)ユーザーIDを設定する処理が実行されていない
2. (ユーザーIDで検索した場合)意図したユーザーIDが設定できていない
3. セッションデータがアップロードされておらず、Reproにユーザー情報が記録されていない

3については [こちら](https://docs.repro.io/ja/faq/app/sdk/2.md) をご参照ください。



##### ユーザーの情報

ID指定で特定メンバーのみ追加することで、テスト配信用のオーディエンスとしてご利用になれます。
端末情報やマーケティング機能のテスト配信に必要な情報を表示します。
テスト用の配信端末にプッシュ通知を表示させるためには、以下の条件を満たす必要があります。

- プッシュトークンが存在すること
- プッシュトークン利用可否が○であること
- プッシュ通知許諾が○であること

メッセージの表示については特に条件はありません。

###### プッシュトークン

プッシュ通知を配信するために必要なトークンです。
AndroidではRegistration ID、iOSではデバイストークンのことを示します。

###### プッシュトークン利用可否

プッシュトークンの利用可否を表示します。
プッシュトークンが取得できていて、かつプッシュトークンが有効な場合 **○** が表示されます。

プッシュトークンが無効となるケースは以下のとおりです。

- アプリがアンインストールされた状態でプッシュを配信しようとした
- プッシュ用証明書が間違っている状態でプッシュを配信しようとした

##### NOTE
プッシュトークン利用可否が×の状態で以下の操作を行うと、値が○にリセットされます。

- プッシュトークンが取得済みかつプッシュ通知許諾ONの場合に、アプリ起動してセッションをアップロードする
- アプリを再インストールし、プッシュトークンを再度生成した状態でアプリ起動してセッションをアップロードする

###### プッシュ通知許諾

プッシュ通知許諾がONであれば **○** が表示されます。

##### NOTE
OS側のプッシュ通知許諾の状態を表します。
アプリ独自に通知フラグを実装している場合でも、それを表すものではありません。

##### ユーザーの削除

ユーザーを削除するには、一覧から **- (除外)** ボタンをクリックします。





##### ユーザーの詳細画面

ユーザーIDを押下することで、詳細画面に遷移することができます。
詳細画面ではユーザーのユーザープロフィールや、イベント実行回数を確認することができます。



###### ユーザープロフィール

ユーザーに紐づくユーザープロフィールの一覧が表示されます。



###### イベント実行回数

ユーザーが日毎に実行したイベントの総回数を表示します。



##### NOTE
- 一度に検索できるのは最大30日間、イベント5個までです
- 最大90日前まで遡って検索ができます
- イベントプロパティは表示されません
- 実行した時刻は表示されません

### 作成結果の確認

オーディエンスの作成結果を確認できます。また作成結果を更新したい場合は編集ボタンをクリックし、編集画面で更新をしてください。

##### WARNING
更新については [サポートサイトのFAQ](https://support.repro.io/hc/ja/articles/900005692983) に詳細な説明がありますので、こちらも参考にしてください。



#### オーディエンスの情報

オーディエンスに含まれるユーザー数を表示します。算出には数分程度かかる場合があります。計算処理中は **計算中** のアイコンが表示されます。

#### キャンペーン

このオーディエンスを利用しているプッシュ通知やメッセージといったキャンペーンが表示されます。各キャンペーン名はそのオーディエンスを利用しているキャンペーンへのリンクになっています。作成してすぐは **未使用** と表示されます。

### 対象ユーザー数の更新

対象ユーザー数の再計算はオーディエンスの一覧画面、詳細確認画面から行えます。一覧画面では対象ユーザー数にマウスオーバーすることで最終更新時間を確認できます。



### オーディエンスを削除する



オーディエンスの利用数が上限に達すると、それ以上のオーディエンスを作成することができません。一覧画面からオーディエンスを削除し、利用数を減らしてください。

##### WARNING
- ID指定オーディエンスは、利用数に反映されないことから、削除できません
- インポート・フィルターオーディエンスは、キャンペーンから利用されていないときのみ、削除できます
  - 対象のオーディエンスを利用しているキャンペーンがすべてアーカイブされているか、配信が終了している必要があります

---

## デバイスID

デバイスIDはRepro SDKがデバイス識別に使用しているIDです。
OSごとに下記の値を使用しています。

**iOS**

[IDFV (Identifier for Vendor)](https://developer.apple.com/reference/uikit/uidevice/1620059-identifierforvendor)

##### WARNING
IDFVはアプリを再インストールした場合に変更される可能性があります。

**Android**

[ANDROID_ID](https://developer.android.com/reference/android/provider/Settings.Secure.html#ANDROID_ID)  (デフォルト)。サービスのプライバシーポリシーでANDROID_IDの利用を禁止している場合は、アプリの `AndroidManifest.xml` に以下のタグを追加することで、ハッシュ化したANDROID_ID、またはSDKの生成するUUIDをデバイスIDとしてご利用できます。 `android:value` には以下のいずれかを指定してください。

- `"ANDROID_ID"` : デバイスIDとしてANDROID_IDを使用します(デフォルト)
- `"ANDROID_ID_MD5"` : デバイスIDとしてMD5でハッシュ化したANDROID_IDを使用します
- `"UUID"` : デバイスIDとしてSDKの生成するUUIDを使用します。このUUIDは `SharedPreferences` に保存されます。

```xml
<application>
  ...
  <meta-data
      android:name="io.repro.android.DeviceID.Mode"
      android:value="ANDROID_ID"> // Specify "ANDROID_ID", "ANDROID_ID_MD5" or "UUID"
  </meta-data>
  ...
</application>
```

また、 `"ANDROID_ID_MD5"` を指定した場合は以下のタグでハッシュ計算に用いるソルトを指定可能です。`android:value` には任意の文字列を指定できます。

```xml
<application>
  ...
  <meta-data
      android:name="io.repro.android.DeviceID.Salt"
      android:value="mysalt">
  </meta-data>
  ...
</application>
```

##### WARNING
- SDK導入後にデバイスIDの種類を変更した場合は、一時的にプッシュ通知の効果測定の精度が下がる場合があります。
- `"UUID"` を指定した場合は、アプリのアンインストール・再インストールなどで `SharedPreferences` が削除されるとデバイスIDが新しい値となり、プッシュ通知の効果測定の精度が下がる場合があります。



### デバイスIDを取得

上述のデバイスIDを取得します

```objc
NSString* deviceID = [Repro getDeviceID];
```

```swift
let deviceID = Repro.deviceID()
```

```java
String deviceID = Repro.getDeviceID();
```

```kotlin
val deviceID = Repro.getDeviceID()
```

```cpp
const char* deviceID = ReproCpp::getDeviceID();
```

```csharp
string deviceID = Repro.GetDeviceID ();
```

```js-cordova
// retrieve the deviceID via a callback function
Repro.getDeviceID(function(deviceID) {
  ...
});
```

```js-react-native
// retrieve the deviceID via a callback function
Repro.getDeviceID((error, deviceID) => {
  ...
});
```

```dart
final deviceID = await Repro.getDeviceID();
```

---

## ユーザーID

Webサイト固有のユーザーIDを設定できます。ユーザーIDを設定すると、エンドユーザーが複数の端末やブラウザを使っている場合に、異なる端末やブラウザから上がってくるセッション情報を同一ユーザーのものとみなすことができるようになります。

セットするのは、以下のようなユーザーを一意に特定できる文字列です。

- サービスで使用している会員ID

##### WARNING
氏名のような重複する可能性のある文字列をセットしないでください。その場合、同一ユーザーが複数のデバイスやブラウザを利用しているとみなされます。

##### WARNING
メールアドレスや電話番号は変更される可能性があるため、ユーザーIDとしてセットしないでください。セットするユーザーIDが変更された場合、別のユーザーが端末やブラウザを利用しているという扱いになります。

##### WARNING
未ログインの状態で、ユーザーIDをセットしないようにしてください。ユーザーIDがセットされていない状態で記録された行動履歴・ユーザープロフィールは、ユーザーIDをセットした後も引き継がれますが、ログイン前にユーザーIDを明示的に指定してしまった場合、ログイン前とログイン後の行動履歴・ユーザープロフィールが別のユーザーのものとして取り扱われてしまいます。

##### WARNING
ユーザーIDは導入スニペットの後かつ、reproio("setup", "YOUR_REPRO_SDK_TOKEN")よりも前に設定してください。

### ユーザーIDをセットする

上述のユーザーIDをセットします。文字数の上限は191文字です。

```js-web
reproio("setUserID", "xxxxxxxxxxxx");
```

---

## デバイスID

デバイスIDはRepro SDKがデバイス識別に使用しているIDです。

##### WARNING
下記の場合、デバイスIDは新たに発行されます。

- シークレットモードでアクセスする
- Repro導入サイトのドメイン配下で保存されているCookie、およびlocalStorageを削除する



### デバイスIDを取得

上述のデバイスIDを取得します

```js-web
reproio('getDeviceID');
```

---

## セッションがアップロードされないケースは何がありますか？

トラッキングデータなどを含むセッションデータは定期的にサーバーにアップロードされます。

セッションの送信ができていない場合、下記の原因が考えられます。

- ReproSDKの初期化(Repro.Setup)が行われていない
- 開発ソフト上で実行停止した
- アプリがクラッシュして強制終了した
- 後述の要因などにより、セッションを記録してから5日以上経過してセッションをアップロードした

以下の場合は次回アプリ起動時にアップロードされます。

- アプリがバックグラウンドに遷移したタイミングで、ネットワークの不調によりReproのホストへ接続できなかった場合
- [iOS]アプリをバックグラウンドに遷移せずに、タスク一覧から他のアプリに遷移した場合
- [iOS]アプリをバックグラウンドに遷移せずに、タスク一覧からタスクキルした場合

以下の場合は次回アプリ起動時にアップロードされる可能性があります。
タイミング次第ではアップロードはせず、セッションを破棄することもあります。

- [Android]アプリをバックグラウンドに遷移せずにタスク一覧表示後、素早くタスクキルした場合(1秒以内など)

##### NOTE
タスクキルは、アプリをバックグラウンドで実行させず停止させることを指します。操作方法については下記リンクをご確認ください。(機種によっては操作方法が異なる場合があります。)

- [Android] [https://support.google.com/pixelphone/answer/2781964#close_apps](https://support.google.com/pixelphone/answer/2781964#close_apps)
- [iOS] [https://support.apple.com/ja-jp/HT201330](https://support.apple.com/ja-jp/HT201330)

### 確認方法

セッションが送信された場合、[ログレベル](https://docs.repro.io/ja/dev/sdk/log.md) を DEBUG に変更することでAndroid Studio・Xcodeにて下記のようなログが出力されます。

#### iOS

```
2018-01-01 12:47:35.758135+0900 ReproDemo[2929:135194] DEBUG: Repro Upload 2069_9DCEBAE6-F0C3-41FE-AB87-4BDC78317784_20180101034730743.log.gz

2018-01-01 12:47:35.880139+0900 ReproDemo[2929:135194] DEBUG: Repro Upload Complete: 2069_9DCEBAE6-F0C3-41FE-AB87-4BDC78317784_20180101034730743.log.gz
```

#### Android

```
2018-01-01 16:29:25.980 9070-9210/com.example.xxxx.sampleapp D/Repro: Upload 5460_9a0876cfa4f5a631_20180817072924223.log.gz

2018-01-01 16:29:26.227 9070-9179/com.example.xxxx.sampleapp D/Repro: Uploaded 5460_9a0876cfa4f5a631_20180817072924223.log.gz
```

---

## ログレベル

SDKは自動で出力するログがあり、その内容からSDKの挙動を確認できます。ログレベルを指定することで、ログの流量をコントロールします。

ログレベルは、SDKが出力するログの「詳細度」を制御する設定です。レベル（優先順位）が高いほど詳細度が低くなり、出力される情報は少なくなります。

下記からログレベルを選択し、変更できます。

- `Error`
- `Warning`
- `Info` (by default)
- `Debug`

ログレベル毎に出力されるログは次のようになります。

| ログレベル | 説明 |
| --- | --- |
| `Error` | 最も詳細度の低いレベルです。SDKの処理が失敗した場合にログが出力されます。 |
| `Warning` | SDKがリトライ可能・回復可能な問題のログが出力されます。 |
| `Info` | SDKの主要動作のログが出力されます。これがデフォルトのレベルです。 |
| `Debug` | 最も詳細度の高いレベルです。SDKの内部動作のログが出力されます。 |

##### NOTE
特定のログレベルを指定すると、そのレベルより詳細度の低いログが全て出力されます。

SDKの動作検証では、詳細度の最も高い `Debug` を指定してください。
`Debug` を指定すると、実装した [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md) や [ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md) など動作検証に有用なログを確認できます。

リリース時はユーザーの端末負荷を抑えるために詳細度の低いレベルを指定することをお勧めします。

**ログの出力箇所**

ログはIDEのコンソール上に出力されます。

iOS（Xcode）およびAndroid（AndroidStudio）においてそれぞれ次の箇所に出力されます。

- iOS（Xcode）：[View] > [Debug Area] > [Activate Console]
- Android（AndroidStudio）：[View] > [Tool Windows] > [Logcat]

### ログレベルを変更する

```objc
// ERROR
[Repro setLogLevel:RPRLogLevelError];

// WARNING
[Repro setLogLevel:RPRLogLevelWarn];

// INFO
[Repro setLogLevel:RPRLogLevelInfo];

// DEBUG
[Repro setLogLevel:RPRLogLevelDebug];
```

```swift
// ERROR
Repro.set(logLevel: .error)

// WARNING
Repro.set(logLevel: .warn)

// INFO
Repro.set(logLevel: .info)

// DEBUG
Repro.set(logLevel: .debug)
```

```java
// ERROR
Repro.setLogLevel(Log.ERROR);

// WARNING
Repro.setLogLevel(Log.WARN);

// INFO
Repro.setLogLevel(Log.INFO);

// DEBUG
Repro.setLogLevel(Log.DEBUG);
```

```kotlin
// ERROR
Repro.setLogLevel(Log.ERROR)

// WARNING
Repro.setLogLevel(Log.WARN)

// INFO
Repro.setLogLevel(Log.INFO)

// DEBUG
Repro.setLogLevel(Log.DEBUG)
```

```cpp
// ERROR
ReproCpp::setLogLevel("Error");

// WARNING
ReproCpp::setLogLevel("Warn");

// INFO
ReproCpp::setLogLevel("Info");

// DEBUG
ReproCpp::setLogLevel("Debug");
```

```csharp
// ERROR
Repro.SetLogLevel ("Error");

// WARNING
Repro.SetLogLevel ("Warn");

// INFO
Repro.SetLogLevel ("Info");

// DEBUG
Repro.SetLogLevel ("Debug");
```

```js-cordova
// ERROR
Repro.setLogLevel("Error");

// WARNING
Repro.setLogLevel("Warn");

// INFO
Repro.setLogLevel("Info");

// DEBUG
Repro.setLogLevel("Debug");
```

```js-react-native
// ERROR
Repro.setLogLevel(Repro.LOGLEVEL_ERROR);

// WARNING
Repro.setLogLevel(Repro.LOGLEVEL_WARN);

// INFO
Repro.setLogLevel(Repro.LOGLEVEL_INFO);

// DEBUG
Repro.setLogLevel(Repro.LOGLEVEL_DEBUG);
```

```dart
// ERROR
await Repro.setLogLevel(LogLevel.error);

// WARNING
await Repro.setLogLevel(LogLevel.warn);

// INFO
await Repro.setLogLevel(LogLevel.info);

// DEBUG
await Repro.setLogLevel(LogLevel.debug);
```

---

## ユーザーの定義

ユーザーとは、Repro上で取り扱うアプリやWebサイトのエンドユーザーのことを指しており、それぞれのユーザーは下記の様に一意性を担保しています。

**ユーザーIDをセットしている場合**

- [ユーザーID](https://docs.repro.io/ja/dev/sdk/user-id.md)

**ユーザーIDをセットしていない場合**

- iOS:  [IDFV (Identifier for Vendor)](https://developer.apple.com/reference/uikit/uidevice/1620059-identifierforvendor)
- Android:  [ANDROID_ID](https://developer.android.com/reference/android/provider/Settings.Secure.html#ANDROID_ID)
- Web: ブラウザごとにランダムに生成した [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier)

### 新規ユーザー

新規ユーザーは、初回セッション(ReproのSDKが組み込まれて以降に初めてアプリやWebサイトを利用した際に送られるセッション)をアップロードしたユーザーを指します。新規ユーザーのアクションとして扱われる期間は以下の通りです。

1. **日次の集計結果**: 初回セッションの保存処理が行われてから24時間
2. **週次の集計結果**: 初回セッションの保存処理が行われてから当週の日曜日まで
3. **月次の集計結果**: 初回セッションの保存処理が行われてから当月の末日まで

##### WARNING
仕様変更(2018/4/11)

一度ユーザーIDがセットされたことのあるデバイスで、過去に登録されたことのないユーザーIDがセットされた場合、新規ユーザーとみなされます。

### ユーザーとデバイスの関係（iOS/Android）

デバイスとは、ReproのSDKが組み込まれているアプリがインストールされたスマートフォンデバイスの事を指しています。
また、デバイスの一意性は [デバイスID(IDFV/ANDROID_ID)](https://docs.repro.io/ja/dev/sdk/device-id.md) で担保しています。

デバイスとユーザーの紐付きには下記のパターンがあります。

**1人のユーザーが複数デバイスを所持している場合**
: - 1人のユーザーが異なるデバイス間で同一のユーザーIDを使用すると、それぞれのデバイス上のユーザーがRepro上でユーザー同定され、トラッキングされたデータが紐づきます。

**1つのデバイスを複数のユーザーで共有している場合**
: - 当該デバイスへ最後にセットされたユーザーIDと当該デバイスが紐付き、過去に紐付いていたユーザーは当該デバイスとの紐付きが解消されます。
  - デバイスとの紐付きが解消されたユーザーは、デバイス単位で対象管理されているプッシュ通知の対象から外れます。
  - ユーザーIDをセットしていない場合、当該デバイスを複数のユーザーが操作していたとしてもRepro上では1人のユーザーとして扱われます。

### ユーザーとブラウザの関係（Web）

ReproのWeb SDKはブラウザごとに一意な文字列を生成しCookieに保存することでブラウザを識別します。
エンドユーザーが複数のブラウザを利用している場合、ブラウザとユーザーの紐付きには下記のパターンがあります。

**1人のユーザーが複数ブラウザを利用している場合**
: - 1人のユーザーが異なるブラウザ間で同一のユーザーIDを使用すると、それぞれのブラウザ上のユーザーがRepro上でユーザー同定され、トラッキングされたデータが紐づきます。

**1つのブラウザを複数のユーザーで利用している場合**
: - 当該ブラウザへ最後にセットされたユーザーIDと当該ブラウザが紐付き、過去に紐付いていたユーザーは当該ブラウザとの紐付きが解消されます。
  - ユーザーIDをセットしていない場合、当該ブラウザを複数のユーザーが操作していたとしてもRepro上では1人のユーザーとして扱われます。

---

## ニュースフィード

ニュースフィードを利用することで、プッシュ通知（スタンダード形式で作成されたもの）、アプリ内メッセージ および Webメッセージの履歴の取得が可能です。

### ニュースフィードの仕様について

#### 一度に取得可能なキャンペーン数

最新のキャンペーンから遡って最大で **200** 通まで一度に取得可能です。200を超えて取得したい場合は、レスポンスの末尾の要素のIDを [オフセットを利用して取得](#get-by-offset) のパラメータとして利用し、再度取得をしてください。

##### WARNING
プッシュ通知のキャンペーンの履歴をニュースフィード機能で取得するためには、以下のいずれかの SDK を利用する必要があります。

* Android SDK 5.0.1 以上
* iOS SDK 4.8.0 以上
* Unity SDK 6.0.0 以上
* React Native SDK 3.0.0 以上
* Cordova Plugin 6.0.0 以上
* Cocos2d-x SDK 5.0.0 以上
* Flutter Package 1.0.0 以上

また、アプリ内メッセージおよびWebメッセージの履歴を取得するためには、以下のいずれかの SDK が必要です。

* Android SDK 5.6.0 以上
* iOS SDK 5.8.0 以上
* Unity SDK 6.7.0 以上
* React Native SDK 3.7.0 以上
* Cordova Plugin 6.7.0 以上
* Cocos2d-x SDK 5.7.0 以上
* Flutter Package 2.0.0 以上

##### WARNING
ニュースフィードの機能を利用するには、以下の通りにキャンペーンが作成されている必要があります。

1. 当該のキャンペーンはスタンダード形式で作成されている。（プッシュ通知の場合）
2. キャンペーンの作成時に「通知をニュースフィードとして使う」のチェックボックスにチェックしてある。

##### WARNING
カスタム JSON や PUSH API が指定されているキャンペーンはニュースフィードとして利用することができません。ご注意ください。

#### 遡ることの出来るキャンペーン期間

リクエスト日を起点にして、 **30日以内** に配信されたキャンペーンが取得可能です。

### ニュースフィードインターフェース

#### データ形式

ニュースフィードは以下のようなデータ形式になっています。

```java
public class NewsFeedEntry {

    public final long id;
    public final NewsFeedCampaignType campaignType;
    public final String deviceID;
    public final String title;
    public final String summary;
    public final String body;
    public final Uri linkUrl;                         // Deprecated
    public final String linkUrlString;
    public final Uri imageUrl;                        // Deprecated
    public final String imageUrlString;
    public final Date deliveredAt;
    public boolean shown;
    public boolean read;

    public NewsFeed(JSONObject json);
}
```

```kotlin
class NewsFeedEntry (

    val id: Long,
    val campaignType: NewsFeedCampaignType,
    val deviceID: String,
    val title: String,
    val summary: String,
    val body: String,
    val linkUrl: Uri,                 // Deprecated
    val linkUrlString: String,
    val imageUrl: Uri,                // Deprecated
    val imageUrlString: String,
    val deliveredAt: Date,
    var shown: Boolean,
    var read: Boolean
)
```

```objc
@interface RPRNewsFeedEntry : NSObject

@property (nonatomic, readonly)           uint64_t ID;
@property (nonatomic, readonly)           NSString *deviceID;
@property (nonatomic, readonly)           NSString *title;
@property (nonatomic, readonly)           NSString *summary;
@property (nonatomic, readonly)           NSString *body;
@property (nonatomic, readonly)           RPRCampaignType campaignType;
@property (nonatomic, readonly, nullable) NSURL *linkUrl;                // Deprecated
@property (nonatomic, readonly)           NSString *linkUrlString;
@property (nonatomic, readonly, nullable) NSURL *imageUrl;               // Deprecated
@property (nonatomic, readonly)           NSString *imageUrlString;
@property (nonatomic, readonly)           NSDate *deliveredAt;
@property (nonatomic)                     BOOL shown;
@property (nonatomic)                     BOOL read;

@end
```

```swift
class RPRNewsFeedEntry: NSObject {
    private(set) var ID: UInt64
    private(set) var deviceID: String?
    private(set) var title: String?
    private(set) var summary: String?
    private(set) var body: String?
    private(set) var campaignType: RPRCampaignType
    private(set) var linkUrl: URL?                    // Deprecated
    private(set) var linkUrlString: String?
    private(set) var imageUrl: URL?                   // Deprecated
    private(set) var imageUrlString: String?
    private(set) var deliveredAt: Date?
    var shown = false
    var read = false
}
```

```cpp
class ReproCpp {

public:

    class NewsFeedEntry {

    public:

        uint64_t getID();
        const char * getDeviceID();
        const char * getTitle();
        const char * getSummary();
        const char * getBody();
        ReproCpp::CampaignType getCampaignType();
        const char * getLinkUrl();                   // Deprecated
        const char * getLinkUrlString();
        const char * getImageUrl();                  // Deprecated
        const char * getImageUrlString();
        time_t getDeliveredAt();
        bool getShown();
        bool getRead();
        void setShown(bool value);
        void setRead(bool value);
    };
};
```

```csharp
public class NewsFeedEntry
{
    public long Id { get; }
    public NewsFeedCampaignType CampaignType { get; }
    public string DeviceID { get; }
    public string Title { get; }
    public string Summary { get; }
    public string Body { get; }
    public Uri LinkUrl { get; }                        // Deprecated
    public string LinkUrlString { get; }
    public Uri ImageUrl { get; }                       // Deprecated
    public string ImageUrlString { get; }
    public DateTime DeliveredAt { get; }
    public bool Shown { get; set; }
    public bool Read { get; set; }
    public Dictionary<string, string> Extras { get; }
}
```

```js-react-native
class NewsFeedEntry {
    constructor(value) {
        this.id; // number
        this.deviceID; // string
        this.title; // string
        this.summary; // string
        this.body; // string
        this.campaignType; // integer
        this.deliveredAt; // string
        this.linkUrl; // Deprecated
        this.linkUrlString; // string
        this.imageUrl; // Deprecated
        this.imageUrlString; // string
        this.shown; // boolean
        this.read; // boolean
    }
}
```

```js-cordova
/**
* @property {number}       newsfeed_id      - The newsfeed id
* @property {string}       device_id        - The end user's device id
* @property {string}       title            - The campaign's title
* @property {string}       summary          - The campaign's summary
* @property {string}       body             - The campaign's body
* @property {string}       delivered_at     - The campaign's delivered date time
* @property {string}       link_url         - Deprecated
* @property {string}       link_url_string  - The campaign's link url
* @property {string}       image_url        - Deprecated
* @property {string}       image_url_string - The campaign's image url
* @property {string}       campaign_type    - The campaign's type("in_app_message" or "web_message" or "push_notification" or "all")
* @property {boolean}      shown            - Indicate whether the newsfeed has been shown to end user
* @property {boolean}      read             - Indicate whether the newsfeed has been read by end user
*/

{
    "newsfeed_id":      1,
    "device_id":        "123456789",
    "title":            "The title",
    "summary":          "The summary",
    "body":             "The body",
    "delivered_at":     "XXXX-XX-XXTXX:XX:XX+XX:XXXX",
    "link_url":         "https://example.com",
    "link_url_string":  "https://example.com",
    "image_url":        "https://example.com/example.jpeg",
    "image_url_string": "https://example.com/example.jpeg",
    "campaign_type":    "in_app_message",
    "shown":            true,
    "read":             false
}
```

```dart
// For Flutter Package below version 3.0.0
class NewsFeedEntry {
    int get id;
    NewsFeedCampaignType get campaignType;
    String get deviceID;
    String get title;
    String get summary;
    String get body;
    String get linkUrl;       // Deprecated
    String get linkUrlString;
    String get imageUrl;      // Deprecated
    String get imageUrlString;
    DateTime get deliveredAt; // UTC Date
    String get rawDeliveredAt;

// For Flutter Package version 3.0.0 and above
class NewsFeedEntry {
    int get id;
    NewsFeedCampaignType get campaignType;
    String get deviceID;
    String get title;
    String get summary;
    String get body;
    String? get linkUrl;       // Deprecated
    String? get linkUrlString;
    String? get imageUrl;      // Deprecated
    String? get imageUrlString;
    DateTime? get deliveredAt; // UTC Date
    String? get rawDeliveredAt;
    bool shown;
    bool read;
}
```

##### WARNING
`link_url` `image_url` は非推奨となっています。同じデータを持っている `link_url_string` `image_url_string` をご利用ください。

* 理由: URLにマルチバイト文字を使用した場合に、OSによって正しく変換されないことがあったため、非推奨としております（例: `NSURL` ）

`link_url_string` `image_url_string` は以下の SDK をご利用の場合のみ取得可能です。

* Android SDK 5.16.0 以上
* iOS SDK 5.17.0 以上
* Unity SDK 6.18.0 以上
* React Native SDK 3.19.0 以上
* Cordova Plugin 6.19.0 以上
* Cocos2d-x SDK 5.18.0 以上
* Flutter Package 3.10.0 以上

`link_url_string` `image_url_string` は、文字列もしくは空文字が設定されます。

`link_url` を設定しなかった場合、返り値として **null** が設定されますが、2022/03/08以前に作成されたキャンペーンにつきましては、空文字が返る可能性があります。

また、キャンペーン種別として指定可能な値は以下のデータ形式となっています。

```java
public enum NewsFeedCampaignType {
    PushNotification,
    InAppMessage,
    WebMessage,
    All
}
```

```kotlin
enum class NewsFeedCampaignType {
    PushNotification,
    InAppMessage,
    WebMessage,
    All
}
```

```objc
typedef NS_ENUM(NSUInteger, RPRCampaignType) {
    RPRCampaignTypePushNotification,
    RPRCampaignTypeInAppMessage,
    RPRCampaignTypeWebMessage,
    RPRCampaignTypeAll
};
```

```swift
enum RPRCampaignType {
    case pushNotification
    case inAppMessage
    case webMessage
    case all
}
```

```cpp
enum class CampaignType : uint64_t {
    PushNotification,
    InAppMessage,
    WebMessage,
    All,
};
```

```csharp
public enum NewsFeedCampaignType
{
    PushNotification,
    InAppMessage,
    WebMessage,
    All
}
```

```js-react-native
Repro.CAMPAIGN_TYPE_PUSH_NOTIFICATION;
Repro.CAMPAIGN_TYPE_IN_APP_MESSAGE;
Repro.CAMPAIGN_TYPE_WEB_MESSAGE;
Repro.CAMPAIGN_TYPE_ALL;
```

```js-cordova
Repro.CampaignType.InAppMessage
Repro.CampaignType.PushNotification
Repro.CampaignType.WebMessage
Repro.CampaignType.All
```

```dart
enum NewsFeedCampaignType {
    PushNotification,
    InAppMessage,
    WebMessage,
    All
}
```

##### WARNING
`CampaignType` およびこれを利用するフィールドは、以下の SDK をご利用の場合のみ取得可能です。

* Android SDK 5.6.0 以上
* iOS SDK 5.8.0 以上
* Unity SDK 6.7.0 以上
* React Native SDK 3.7.0 以上
* Cordova Plugin 6.7.0 以上
* Cocos2d-x SDK 5.7.0 以上
* Flutter Package 2.0.0 以上

#### ニュースフィードを取得する

##### 取得インターフェース

```java
public final class Repro {
    // Android SDK 5.0.1 or later
    public static List<NewsFeedEntry> getNewsFeeds(final int limit) throws IOException, RuntimeException;
    public static List<NewsFeedEntry> getNewsFeeds(final int limit, final long offsetID) throws IOException, RuntimeException;

    // Only for Android SDK 5.6.0 or later
    public static List<NewsFeedEntry> getNewsFeeds(final int limit, final NewsFeedCampaignType campaignType) throws IOException, RuntimeException;
    public static List<NewsFeedEntry> getNewsFeeds(final int limit, final long offsetID, final NewsFeedCampaignType campaignType) throws IOException, RuntimeException;
}
```

```kotlin
object Repro {

    // Android SDK 5.0.1 or later
    @Throws(IOException::class, RuntimeException::class)
    fun getNewsFeeds(limit: Int): List<NewsFeedEntry>
    @Throws(IOException::class, RuntimeException::class)
    fun getNewsFeeds(limit: Int, offsetID: Long): List<NewsFeedEntry>

    // Only for Android SDK 5.6.0 or later
    @Throws(IOException::class, RuntimeException::class)
    fun getNewsFeeds(limit: Int, campaignType: NewsFeedCampaignType): List<NewsFeedEntry>
    @Throws(IOException::class, RuntimeException::class)
    fun getNewsFeeds(limit: Int, offsetID: Long, campaignType: NewsFeedCampaignType): List<NewsFeedEntry>
}
```

```objc
@interface Repro : NSObject

// iOS SDK 4.8.0 or later
+ (nullable NSArray<RPRNewsFeedEntry *> *)getNewsFeeds:(uint64_t)limit
                                                 error:(NSError * _Nullable * _Nullable)error
+ (nullable NSArray<RPRNewsFeedEntry *> *)getNewsFeeds:(uint64_t)limit
                                              offsetID:(uint64_t)offsetID
                                                 error:(NSError * _Nullable * _Nullable)error

// Only iOS SDK 5.8.0 or later
+ (nullable NSArray<RPRNewsFeedEntry *> *)getNewsFeeds:(uint64_t)limit
                                          campaignType:(RPRCampaignType)campaignType
                                                 error:(NSError * _Nullable * _Nullable)error
+ (nullable NSArray<RPRNewsFeedEntry *> *)getNewsFeeds:(uint64_t)limit
                                              offsetID:(uint64_t)offsetID
                                          campaignType:(RPRCampaignType)campaignType
                                                 error:(NSError * _Nullable * _Nullable)error

@end
```

```swift
class Repro: NSObject {
    // iOS SDK 4.8.0 or later
    class func getNewsFeeds(_ limit: UInt64) throws -> [RPRNewsFeedEntry]?
    class func getNewsFeeds(_ limit: UInt64, offsetID: UInt64) throws -> [RPRNewsFeedEntry]?

    // Only iOS SDK 5.8.0 or later
    class func getNewsFeeds(_ limit: UInt64, campaignType: RPRCampaignType) throws -> [RPRNewsFeedEntry]?
    class func getNewsFeeds(_ limit: UInt64, offsetID: UInt64, campaignType: RPRCampaignType) throws -> [RPRNewsFeedEntry]?
}
```

```cpp
class ReproCpp {

public:

    // Cocos2d-x SDK 5.0.0 or later
    static std::vector<ReproCpp::NewsFeedEntry> getNewsFeeds(uint64_t limit, bool *error);
    static std::vector<ReproCpp::NewsFeedEntry> getNewsFeeds(uint64_t limit, uint64_t offsetID, bool *error);

    // Only Cocos2d-x SDK 5.7.0 or later
    static std::vector<ReproCpp::NewsFeedEntry> getNewsFeeds(uint64_t limit, ReproCpp::CampaignType campaignType, bool *error);
    static std::vector<ReproCpp::NewsFeedEntry> getNewsFeeds(uint64_t limit, uint64_t offsetID, ReproCpp::CampaignType campaignType, bool *error);
};
```

```csharp
public class Repro
{
    // Unity SDK 6.0.0—6.6.0
    public static List<NewsFeedEntry> GetNewsFeeds(int limit);
    public static List<NewsFeedEntry> GetNewsFeeds(int limit, long offsetID);

    // Unity SDK 6.7.0 or later
    public static List<NewsFeedEntry> GetNewsFeeds(int limit, NewsFeedCampaignType campaignType = NewsFeedCampaignType.PushNotification);
    public static List<NewsFeedEntry> GetNewsFeeds(int limit, long offsetID, NewsFeedCampaignType campaignType = NewsFeedCampaignType.PushNotification);
}
```

```js-react-native
const Repro = {
    // React Native SDK 3.0.0 or later
    getNewsFeeds: (limit, callback) => void,
    getNewsFeedsFor: (limit, offsetID, callback) => void,

    // Only React Native SDK 3.7.0 or later
    getNewsFeedsWithCampaignType: (limit, campaignType, callback) => void,
    getNewsFeedsWithCampaignTypeFor: (limit, offsetID, campaignType, callback) => void,
}
```

```js-cordova
const Repro = {
    // Cordova Plugin 6.0.0 or later
    getNewsFeedsWithLimit: (limit, successCallback, errorCallback) => void,
    getNewsFeedsWithLimitAndOffsetId: (limit, offsetId, successCallback, errorCallback) => void,

    // Cordova Plugin 6.7.0 or later
    getNewsFeedsWithLimitAndCampaignType: (limit, campaignType, successCallback, errorCallback) => void,
    getNewsFeedsWithLimitAndOffsetIdAndCampaignType: (limit, offsetId, campaignType, successCallback, errorCallback) => void
}
```

```dart
class Repro {
    // Flutter Package version 1.X.X
    static Future<List<NewsFeedEntry>> getNewsFeeds(int limit, [int offsetID])

    // Flutter Package version 2.X.X
    static Future<List<NewsFeedEntry>> getNewsFeeds({ @required int limit, int offsetID, @required NewsFeedCampaignType campaignType })

    // Flutter Package version 3.X.X
    static Future<List<NewsFeedEntry>> getNewsFeeds({ required int limit, int? offsetID, required NewsFeedCampaignType campaignType })
}
```

##### WARNING
ご利用中の SDK のバージョンによって、使用可能なメソッドが異なります。

##### WARNING
キャンペーン種別 ( `campaignType` ) の指定のないメソッドを実行した場合は、ご利用中の SDK のバージョンによらずプッシュ通知の履歴 **のみ** が取得されます。

##### 最新のキャンペーン20通を取得する実装例

以下では、最新のキャンペーン20通をニュースフィードとして取得する処理を例にあげます。

```java
new Thread(new Runnable() {
    @Override
    public void run() {
        // Get 20 campaigns as a newsfeed
        List<NewsFeedEntry> newsFeedEntries;
        try {
            // Android SDK 5.0.1 or later
            // (Get only push notification histories)
            newsFeedEntries = Repro.getNewsFeeds(20);

            // Android SDK 5.6.0 or later
            newsFeedEntries = Repro.getNewsFeeds(20, NewsFeedCampaignType.PushNotification);
        } catch (IOException e) {
            // Error handling
            ...
        } catch (RuntimeException e) {
            // Error handling
            ...
        }
    }
}).start();
```

```kotlin
Thread {
    // Get 20 campaigns as a newsfeed
    try {
        // Android SDK 5.0.1 or later
        // (Get only push notification histories)
        var newsFeedEntries = Repro.getNewsFeeds(20)

        // Android SDK 5.6.0 or later
        newsFeedEntries = Repro.getNewsFeeds(20, NewsFeedCampaignType.PushNotification)

    } catch (e: IOException) {
        // Error handling
        ...
    } catch (e: RuntimeException) {
        // Error handling
        ...
    }
}.start()
```

```objc
...

// iOS SDK 4.8.0 or later
NSError *error = nil;
NSArray<RPRNewsFeedEntry *> *newsFeeds = [Repro getNewsFeeds:20 error:&error];
if (error) {
    // Error handling
}

// iOS SDK 5.8.0 or later
NSError *error = nil;
NSArray<RPRNewsFeedEntry *> *newsFeedEntries = [Repro getNewsFeeds:20
                                                      campaignType:RPRCampaignTypePushNotification
                                                             error:&error];
if (error) {
    // Error handling
}

...
```

```swift
...

// iOS SDK 4.8.0 or later
var newsFeeds: [RPRNewsFeedEntry]?
do {
    newsFeeds = try Repro.getNewsFeeds(20)
} catch {
    // Error handling
}

// iOS SDK 5.8.0 or later
var newsFeeds: [RPRNewsFeedEntry]?
do {
    newsFeeds = try Repro.getNewsFeeds(20, campaignType: .pushNotification)
} catch {
    // Error handling
}

...
```

```cpp
...

// Cocos2d-x SDK 5.0.0 or later
bool error;
std::vector<ReproCpp::NewsFeedEntry> newsFeeds = ReproCpp::getNewsFeeds(20, &error);
if (error) {
    // Error handling
}

// Cocos2d-x SDK 5.7.0 or later
bool error;
std::vector<ReproCpp::NewsFeedEntry> newsFeeds = ReproCpp::getNewsFeeds(20, ReproCpp::CampaignType::PushNotification, &error);
if (error) {
    // Error handling
}

...
```

```csharp
...

// Get only push notification histories
var newsFeedEntries = Repro.GetNewsFeeds(20);

// Unity SDK 6.7.0 or later
var newsFeedEntries = Repro.GetNewsFeeds(20, NewsFeedCampaignType.PushNotification);

...
```

```js-react-native
...

// React Native SDK 3.0.0 or later
Repro.getNewsFeeds(20, (_, newsFeeds) => {
    ...
});

// React Native SDK 3.7.0 or later
Repro.getNewsFeedsWithCampaignType(20, Repro.CAMPAIGN_TYPE_PUSH_NOTIFICATION, (_, newsFeeds) => {
    ...
});

...
```

```js-cordova
...

// Cordova Plugin 6.0.0 or later
Repro.getNewsFeedsWithLimit(
    20,
    (newsFeeds) => {
        ...
    },
    (error) => {
        // Error handling
    }
);

// Cordova Plugin 6.7.0 or later
Repro.getNewsFeedsWithLimitAndCampaignType(
    20,
    Repro.CampaignType.InAppMessage,
    (newsFeeds) => {
        ...
    },
    (error) => {
        // Error handling
    }
);

...
```

```dart
...

// Flutter Package 1.0.0—1.6.0
final newsfeeds = await Repro.getNewsFeeds(20);

// Flutter Package 2.0.0 or later
final newsfeeds = await Repro.getNewsFeeds(limit: 20, campaignType: NewsFeedCampaignType.PushNotification)

...
```



##### オフセットを指定し、それ以後のキャンペーン20通を取得する実装例

以下では、あるキャンペーン以後の（そのキャンペーンに対応するIDが1111であるとします。）キャンペーン20通をニュースフィードとして取得する処理を例にあげます。

```java
new Thread(new Runnable() {
    @Override
    public void run() {
        List<NewsFeedEntry> newsFeedEntries;
        try {
            // Get 20 campaigns as a newsfeed
            List<NewsFeedEntry> feeds = Repro.getNewsFeeds(20);
            if (feeds != null && !feeds.isEmpty()) {
                // Get the ID of the last item (1111)
                long lastItemId = feeds.get(feeds.size() - 1).id; // 1111

                // Android SDK 5.0.1 or later
                // (Get only push notification histories)
                newsFeedEntries = Repro.getNewsFeeds(20, lastItemId);

                // Android SDK 5.6.0 or later
                newsFeedEntries = Repro.getNewsFeeds(20, lastItemId, NewsFeedCampaignType.PushNotification);
            }
        } catch (IOException e) {
            // Error handling
            ...
        } catch (RuntimeException e) {
            // Error handling
            ...
        }
    }
}).start();
```

```kotlin
Thread {
    try {
        // Get 20 campaigns as a newsfeed
        val feeds = Repro.getNewsFeeds(20)
        if (!feeds.isNullOrEmpty()) {
            // Get the ID of the last item (1111)
            val lastItemId = feeds.last().id

            // Android SDK 5.0.1 or later
            // (Get only push notification histories)
            val newsFeedEntries = Repro.getNewsFeeds(20, lastItemId)

            // Android SDK 5.6.0 or later
            val newsFeedEntries = Repro.getNewsFeeds(20, lastItemId, NewsFeedCampaignType.PushNotification)
        }
    } catch (e: IOException) {
        // Error handling
        ...
    } catch (e: RuntimeException) {
        // Error handling
        ...
    }
}.start()
```

```objc
...

// Get 20 campaigns as a newsfeed
NSError *error = nil;
NSArray<RPRNewsFeedEntry *> *feeds = [Repro getNewsFeeds:20 error:&error];
if (error == nil && feeds != nil && feeds.count > 0) {
    // Get the ID of the last item (1111)
    uint64_t lastItemId = feeds.lastObject.ID;

    // iOS SDK 4.8.0 or later
    NSArray<RPRNewsFeedEntry *> *newsFeedEntries = [Repro getNewsFeeds:20 offsetID:lastItemId error:&error];
    if (error) {
        // Error handling
    }

    // iOS SDK 5.8.0 or later
    NSArray<RPRNewsFeedEntry *> *newsFeedEntries = [Repro getNewsFeeds:20
                                                              offsetID:lastItemId
                                                          campaignType:RPRCampaignTypePushNotification
                                                                 error:&error];
    if (error) {
        // Error handling
    }
}

...
```

```swift
...

do {
    // Get 20 campaigns as a newsfeed
    let feeds = try Repro.getNewsFeeds(20)
    if !feeds.isEmpty {
        // Get the ID of the last item (1111)
        let lastItemId = feeds.last!.id

        // iOS SDK 4.8.0 or later
        let newsFeeds = try Repro.getNewsFeeds(20, offsetID: lastItemId)

        // iOS SDK 5.8.0 or later
        let newsFeeds = try Repro.getNewsFeeds(20, offsetID: lastItemId, campaignType: .pushNotification)
    }
} catch {
    // Error handling
}

...
```

```cpp
...

// Get 20 campaigns as a newsfeed
bool error = false;
std::vector<ReproCpp::NewsFeedEntry> feeds = ReproCpp::getNewsFeeds(20, &error);
if(!error && !feeds.empty()) {
    // Get the ID of the last item (1111)
    uint64_t lastItemId = feeds.back().getID();

    // Cocos2d-x SDK 5.0.0 or later
    std::vector<ReproCpp::NewsFeedEntry> newsFeeds = ReproCpp::getNewsFeeds(20, lastItemId, &error);
    if (error) {
        // Error handling
    }

    // Cocos2d-x SDK 5.7.0 or later
    std::vector<ReproCpp::NewsFeedEntry> newsFeeds = ReproCpp::getNewsFeeds(20, lastItemId, ReproCpp::CampaignType::PushNotification, &error);
    if (error) {
        // Error handling
    }
}

...
```

```csharp
...

// Get 20 campaigns as a newsfeed
var feeds = Repro.GetNewsFeeds(20);
if (feeds != null && feeds.Count > 0) {
    // Get the ID of the last item (1111)
    var lastItemId = feeds.Last().Id;

    // Unity SDK 6.0.0 or later
    // (Get only push notification histories)
    var newsFeedEntries = Repro.GetNewsFeeds(20, lastItemId);

    // Unity SDK 6.7.0 or later
    var newsFeedEntries = Repro.GetNewsFeeds(20, lastItemId, NewsFeedCampaignType.PushNotification);
}

...
```

```js-react-native
...

// Get 20 campaigns as a newsfeed
Repro.getNewsFeeds(20, (_, feeds) => {
    if (feeds && feeds.length > 0) {
        // Get the ID of the last item (1111)
        const lastItemId = feeds[feeds.length - 1].id;

        // React Native SDK 3.0.0 or later
        Repro.getNewsFeedsFor(20, lastItemId, (_, newsFeeds) => {
            ...
        });

        // React Native SDK 3.7.0 or later
        Repro.getNewsFeedsWithCampaignTypeFor(20, lastItemId, Repro.CAMPAIGN_TYPE_PUSH_NOTIFICATION, (_, newsFeeds) => {
            ...
        });
    }
});

...
```

```js-cordova
...

// Get 20 campaigns as a newsfeed
Repro.getNewsFeedsWithLimit(
    20,
    (feeds) => {
        if (Array.isArray(feeds) && feeds.length > 0) {
            // Get the ID of the last item (1111)
            const lastItemId = feeds[feeds.length - 1].id;

            // Cordova Plugin 6.0.0 or later
            Repro.getNewsFeedsWithLimitAndOffsetId(
                20,
                lastItemId,
                (newsFeeds) => {
                    ...
                },
                (error) => {
                    // Error handling
                }
            );

            // Cordova Plugin 6.7.0 or later
            Repro.getNewsFeedsWithLimitAndOffsetIdAndCampaignType(
                20,
                lastItemId,
                Repro.CampaignType.InAppMessage,
                (newsFeeds) => {
                    ...
                },
                (error) => {
                    // Error handling
                }
            );
        }
    },
    (error) => {
        // Error handling
    }
);

...
```

```dart
...

// Get 20 campaigns as a newsfeed
final feeds = await Repro.getNewsFeeds(20);
if (feeds.isNotEmpty) {
    // Get the ID of the last item (1111)
    final lastItemId = feeds.last.id;

    // Flutter Package 1.0.0—1.6.0
    // (Get only push notification histories)
    final newsfeeds = await Repro.getNewsFeeds(20, lastItemId);

    // Flutter Package 2.0.0 or later
    final newsfeeds = await Repro.getNewsFeeds(limit: 20, offsetID: lastItemId, campaignType: NewsFeedCampaignType.PushNotification);
}

...
```

#### ニュースフィードを更新する

##### 取得インターフェース

```java
public final class Repro {
    public static void updateNewsFeeds(List<NewsFeedEntry> newsFeeds) throws IOException, RuntimeException;
}
```

```kotlin
final class Repro {
    @Throws(IOException::class, RuntimeException::class)
    fun updateNewsFeeds(newsFeeds: List<NewsFeedEntry>)
}
```

```objc
@interface Repro : NSObject

+ (BOOL)updateNewsFeeds:(nonnull NSArray<RPRNewsFeedEntry *> *)newsFeeds error:(NSError * _Nullable * _Nullable)error
NS_SWIFT_NAME(updateNewsFeeds(_:));

@end
```

```swift
class Repro: NSObject {
    class func updateNewsFeeds(_ newsFeeds: [RPRNewsFeedEntry]) throws {
    }
}
```

```cpp
class ReproCpp {

public:

    static bool updateNewsFeeds(std::vector<ReproCpp::NewsFeedEntry> newsFeeds, bool *error);

};
```

```csharp
public class Repro
{
    public static void UpdateNewsFeeds(List<NewsFeedEntry> newsFeeds);
}
```

```js-react-native
const Repro = {
    updateNewsFeeds: (newsFeeds, callback) => void;
}
```

```js-cordova
const Repro = {
    updateNewsFeeds: (newsFeeds, successCallback, errorCallback) => void;
}
```

```dart
class Repro {
    static Future<void> updateNewsFeeds(List<NewsFeedEntry> newsFeeds)
}
```

##### 取得したニュースフィードの中の一通を既読済みに更新する処理の実装例

```java
new Thread(new Runnable() {
    @Override
    public void run() {
        List<NewsFeedEntry> newsFeedEntries = null;
        try {
            // Get 20 newsfeed campaigns
            newsFeedEntries = Repro.getNewsFeeds(20);
        } catch (IOException e) {
            // Error handling
            ...
        } catch (RuntimeException e) {
            // Error handling
            ...
        }

        ...

        if (newsFeedEntries != null && !newsFeedEntries.isEmpty()) {
            // Update procedure
            NewsFeedEntry newsFeedEntry = newsFeedEntries.get(0);
            newsFeedEntry.read = true;

            List<NewsFeedEntry> updateNewsFeedEntries = new ArrayList<>();
            updateNewsFeedEntries.add(newsFeedEntry);
            try {
                Repro.updateNewsFeeds(updateNewsFeedEntries);
            } catch (IOException e) {
                // Error handling
                ...
            } catch (RuntimeException e) {
                // Error handling
                ...
            }
        }
    }
}).start();
```

```kotlin
Thread {
    val newsFeedEntries = try {
        // Get 20 campaigns as a newsfeed
        Repro.getNewsFeeds(20)
    } catch (e: IOException) {
        // Error handling
        ...
        null
    } catch (e: RuntimeException) {
        // Error handling
        ...
        null
    }

    ...

    if (!newsFeedEntries.isNullOrEmpty()) {
        // Update procedure
        val newsFeedEntry = newsFeedEntries[0]
        newsFeedEntry.read = true

        val updateNewsFeedEntries = ArrayList<NewsFeedEntry>()
        updateNewsFeedEntries.add(newsFeedEntry)

        try {
            Repro.updateNewsFeeds(updateNewsFeedEntries)
        } catch (e: IOException) {
            // Error handling
            ...
        } catch (e: RuntimeException) {
            // Error handling
            ...
        }
    }
}.start()
```

```objc
...

// Get 20 campaigns as a newsfeed
NSError *error = nil;
NSArray<RPRNewsFeedEntry *> *newsFeeds = [Repro getNewsFeeds:20 error:&error];

...

if (error == nil && newsFeeds != nil && newsFeeds.count > 0) {
    // Update procedure
    RPRNewsFeedEntry *newsFeed = newsFeeds[0];
    newsFeed.read = true;
    [Repro updateNewsFeeds:@[newsFeed] error:&error];
    if (error) {
        // Error handling
    }
}

...
```

```swift
...

// Get 20 campaigns as a newsfeed
self.newsFeeds = try? Repro.getNewsFeeds(20)

...

if let newsFeed = newsFeeds?.first {
    newsFeed.read = true
    Repro.updateNewsFeeds([newsFeed])
}
```

```cpp
...

// Get 20 newsfeed campaigns
bool error = false;
std::vector<ReproCpp::NewsFeedEntry> newsFeeds = ReproCpp::getNewsFeeds(20, &error);
if (error) {
    // Error handling
}

...

if(!newsFeeds.empty()) {
    // Update procedure
    ReproCpp::NewsFeedEntry newsFeedEntry = newsFeeds[0];
    newsFeedEntry.setRead(true);
    std::vector<ReproCpp::NewsFeedEntry> updateTargets = { newsFeedEntry };
    ReproCpp::updateNewsFeeds(updateTargets, &error);
    if (error) {
        // Error handling
    }
}
```

```csharp
...

// Get 20 newsfeed campaigns
var newsFeedEntries = Repro.getNewsFeeds(20);

...

if (newsFeedEntries != null && newsFeedEntries.Count > 0) {
    // Update procedure
    var newsFeedEntry = newsFeedEntries[0];
    newsFeedEntry.Read = true;
    var updateTargets = new List<NewsFeedEntry> { newsFeedEntry };
    Repro.UpdateNewsFeeds(updateTargets);
}

...
```

```js-react-native
...

let newsfeeds;
// Get 20 newsfeed campaigns
Repro.getNewsFeeds(20, (_, entries) => {
    newsfeeds = entries;
});

...

if (newsfeeds && newsfeeds.length > 0) {
    // Update procedure
    newsfeeds[0].read = true;
    Repro.updateNewsFeeds([newsfeeds[0]], (_) => {
    });
}

...
```

```js-cordova
...

let newsFeedEntries;
// Get 20 newsfeed campaigns
Repro.getNewsFeedsWithLimit(
    20,
    (newsFeeds) => {
        newsFeedEntries = newsFeeds;
    },
    (error) => {
        // Error handling
    }
});

...

if (Array.isArray(newsFeedEntries) && newsFeedEntries.length > 0) {
    // Update procedure
    newsFeedEntries[0].read = true;
    Repro.updateNewsFeeds(
        newsFeedEntries[0],
        (_) => {
            ...
        },
        (error) => {
            // Error handling
        }
    );

...
```

```dart
...

// Get 20 campaigns as a newsfeed
// Flutter Package 1.0.0—1.5.0
final newsFeeds = await Repro.getNewsFeeds(20);

// Flutter Package 2.0.0 or later
final newsFeeds = await Repro.getNewsFeeds(limit: 20, campaignType: NewsFeedCampaignType.PushNotification);

...

if (newsFeeds.isNotEmpty) {
    // Update procedure
    newsFeeds.first.read = true;
    await Repro.updateNewsFeeds([newsFeeds.first]);
}

...
```

---

## Liquidによるパーソナライズ

##### NOTE
ユーザープロフィールやイベントプロパティを変数として差し込むことを検討されている場合、まずは [変数の挿入](https://docs.repro.io/ja/dashboard/campaign/insert-variable.md) をご確認ください。

### 概要

Liquidを活用すれば、プッシュ通知やイベント起点プッシュ通知、アプリ内メッセージ等のReproのキャンペーンでユーザープロフィールやイベントプロパティを変数として差し込み、メッセージの内容をパーソナライズできます。
 
パーソナライズされたメッセージを配信することで、プッシュ通知の開封率や、メッセージのクリック率、CVRの改善が期待できます。
 

### Liquidとは

LiquidとはECプラットフォームのShopifyが開発しているテンプレート言語です。
 
Liquidはオープンソースで開発されておりReproではJavaで実装されている[Liqp](https://github.com/bkiers/Liqp)を利用しています。
 
これはLiquidのJava版の非公式ライブラリであり、利用出来る構文やフィルターが[公式Ruby版のLiquid](https://github.com/Shopify/liquid)とは異なる場合があります。
 
Liquidの詳細は[公式サイト](https://www.shopify.com/jp/blog/partner-shopify-template-language-liquid-overview)を参照してください。
 

### プッシュ通知でのLiquid利用時の注意事項

##### WARNING
- 公開する前に**必ずテスター向けにテスト配信をして、意図した配信がされるか確認**しましょう
  - パーソナライズされたプッシュ通知の配信は既存のキャンペーンとは異なり、複雑なロジックを組むことができます。
  - 結果的に通常のキャンペーン以上に**意図しない配信やメッセージの表示の事故が発生する可能性**があります
- `{{}}` の書き忘れに注意しましょう
  - `user_profile['name']`
    のみ書いた場合、保存時にエラーにはならずそのまま配信されてしまいます
- **必ずユーザープロフィール、イベントプロパティのいずれかを差し込んだLiquidを記述してください。** ユーザープロフィール、イベントプロパティの差し込みがない場合、**Liquid構文がそのまま配信されます。**
- ユーザープロフィール設定でユーザープロフィールの型を確認したり、配信対象設定でよく登録されている値や配信対象数を確認して意図したユーザープロフィールがセットされているか確認します
  - サポートサイト「FAQ：[ユーザープロフィールの実装後、ユーザーに設定できているか確認する方法はありますか？](https://support.repro.io/hc/ja/articles/23586392155161)」も参考にしてください。
- 配信対象を鑑みて、空の状態で配信されるようなユーザーがいないか確認してください。
- プッシュ通知で利用する場合プッシュAPI、バルクプッシュAPIとの併用できません。
- ユーザープロフィール、イベントプロパティの差し込みには**シングルクォーテーションを利用**してください
  - プッシュ通知、イベント起点プッシュ通知において
    `{{user_profile['ユーザープロフィール名']}}`
    と指定する際、ユーザープロフィール名は必ず `'`
    シングルクォーテーションで括る必要があります
  - イベント起点プッシュ通知で、イベントプロパティを利用する場合も同様に`{{event['プロパティ名']}}`とする必要があります
  - `{{user_profile["ユーザープロフィール名"]}}`
    とダブルクォーテーションが利用されている場合は保存時にエラーとなりキャンペーンを公開できません

### アプリ内メッセージ、WebメッセージでのLiquid利用時の注意事項

##### WARNING
- パーソナライズされたメッセージの表示は既存のキャンペーンとは異なり、複雑なロジックを組むことができます。
- 結果的に通常のキャンペーン以上に**意図しないメッセージの表示の事故が発生する可能性**があります
- `{{}}` の書き忘れに注意しましょう
  - `user_profile['name']`
    のみ書いた場合、保存時にエラーにはならずそのまま配信されてしまいます
- **必ずユーザープロフィール、インセンティブコードのいずれかを差し込んだLiquidを記述してください。** ユーザープロフィール、インセンティブコードの差し込みがない場合、**Liquid構文がそのまま配信されます。**
- ユーザープロフィール設定でユーザープロフィールの型を確認したり、配信対象設定でよく登録されている値や配信対象数を確認して意図したユーザープロフィールがセットされているか確認します
  - サポートサイト「FAQ：[ユーザープロフィールの実装後、ユーザーに設定できているか確認する方法はありますか？](https://support.repro.io/hc/ja/articles/23586392155161)」も参考にしてください。
- 配信対象を鑑みて、空の状態で配信されるようなユーザーがいないか確認してください。
- ユーザープロフィールの差し込みには**シングルクォーテーションを利用**してください
  - アプリ内メッセージ、Webメッセージにおいて
    `{{user_profile['ユーザープロフィール名']}}`
    と指定する際、ユーザープロフィール名は必ず `'`
    シングルクォーテーションで括る必要があります
  - `{{user_profile["ユーザープロフィール名"]}}`
    とダブルクォーテーションが利用されている場合は保存時にエラーとなりキャンペーンを公開できません

<!-- NOTE: ユーザープロフィールの型による設定UIは一時的に全チャネルで無効となっている -->
<!-- ref https://repro.slack.com/archives/C0549A3EC0H/p1747630529705379 -->
<!-- ref https://docs.google.com/document/d/1q4E8h7BQW0EaeTyTmJNUNvDqpdw3acY9AxUAv6MLPdY/edit?tab=t.1bshezh9nr7c#heading=h.7lrj5tfciepu -->
<!-- 変数差し込みUIのユーザープロフィールの型ごとの設定項目 -->
<!-- ------------------------------------------------------ -->
<!-- .. _user-profile-string-setting: -->
<!-- .. warning:: -->
<!-- - HTMLアプリ内メッセージ、 Webメッセージでは、型ごとの設定項目を使用することはできません。 -->
<!-- 文字列型 -->
<!-- ~~~~~~~~ -->
<!-- .. image:: /_static/images/campaign/liquid-personalization-insert-varibale-ui-for-string-type-setting.png -->
<!-- :alt: Liquid personalization insert variable ui for string type setting -->
<!-- 設定項目 -->
<!-- ^^^^^^^^ -->
<!-- **デフォルト値** -->
<!-- ユーザープロフィールの値がセットされていない場合、もしくは空文字の場合に表示するデフォルト値を設定できます。 -->
<!-- **挿入される変数の最大文字数を制限する** -->
<!-- ユーザープロフィールに長い文字列が入っていた際に、デフォルト値を表示するか省略して表示するか選択できます。\ -->
<!-- 例えば最大文字数を ``20`` 、\ ``デフォルト値を表示`` と指定した場合、20文字まではそのまま表示されますが21文字以上の場合はデフォルト値が表示されます。 -->
<!-- また、最大文字数を指定して ``...で省略`` を選択した場合、``…`` を含めて最大文字数に省略されます。 -->
<!-- 例えば最大文字数を ``5`` にした場合、以下のようになります。 -->
<!-- 値が ``あいうえお`` のユーザー → ``あいうえお`` と表示 -->
<!-- 値が ``あいうえおか`` のユーザー → ``あいうえ…`` と表示 -->
<!-- .. note:: -->
<!-- - 文字数は全角、半角問わず計算されます。 -->
<!-- .. _user-profile-int-setting: -->
<!-- 整数型 -->
<!-- ~~~~~~ -->
<!-- .. image:: /_static/images/campaign/liquid-personalization-insert-varibale-ui-for-int-type-setting.png -->
<!-- :alt: Liquid personalization insert variable ui for int type setting -->
<!-- 設定項目 -->
<!-- ^^^^^^^^ -->
<!-- **デフォルト値** -->
<!-- ユーザープロフィールの値がセットされていない場合に表示するデフォルト値を設定できます。 -->
<!-- **数字の単位** -->
<!-- ``円`` や ``ポイント`` 等の数字の単位を指定することで、最大数を超えた場合に ``10000ポイント以上`` という表示にすることが出来ます。 -->
<!-- **挿入される変数の最大数を制限する** -->
<!-- ユーザープロフィールに大きい数値が入っていた際に、``~以上`` という表示にすることが出来ます。 -->
<!-- 例えば最大文字数を ``30000``、数字の単位を ``ポイント`` と指定した場合以下のようになります。 -->
<!-- | 値が ``1000`` のユーザー → ``1000ポイント`` と表示 -->
<!-- | 値が ``30000`` のユーザー → ``30000ポイント`` と表示 -->
<!-- | 値が ``1000000`` のユーザー → ``30000ポイント以上`` と表示 -->
<!-- .. _user-profile-decimal-setting: -->
<!-- 小数型 -->
<!-- ~~~~~~ -->
<!-- .. image:: /_static/images/campaign/liquid-personalization-insert-varibale-ui-for-decimal-type-setting.png -->
<!-- :alt: Liquid personalization insert variable ui for decimal type setting -->
<!-- 設定項目 -->
<!-- ^^^^^^^^ -->
<!-- **デフォルト値** -->
<!-- ユーザープロフィールの値がセットされていない場合に表示するデフォルト値を設定できます。 -->
<!-- **数字の単位** -->
<!-- ``kg`` や ``ポイント`` 等の数字の単位を指定することで、最大数を超えた場合に ``100kg以上`` という表示にすることが出来ます。 -->
<!-- **挿入される変数の最大数を制限する** -->
<!-- ユーザープロフィールに大きい数値が入っていた際に、``~以上`` という表示にすることが出来ます。 -->
<!-- 例えば最大文字数を ``100`` 、数字の単位を ``kg`` と指定した場合以下のようになります。 -->
<!-- | 値が ``50.5`` のユーザー → ``50.5kg`` と表示 -->
<!-- | 値が ``99.9`` のユーザー → ``99.9kg`` と表示 -->
<!-- | 値が ``120.5`` のユーザー → ``120以上`` と表示 -->
<!-- .. _user-profile-datetime-setting: -->
<!-- 日付型 -->
<!-- ~~~~~~ -->
<!-- .. image:: /_static/images/campaign/liquid-personalization-insert-varibale-ui-for-datetime-type-setting.png -->
<!-- :alt: Liquid personalization insert variable ui for datetime type setting -->
<!-- デフォルト値 -->
<!-- ^^^^^^^^^^^^ -->
<!-- ユーザープロフィールの値がセットされていない場合に表示するデフォルト値を設定できます。 -->
<!-- 日付の表示形式 -->
<!-- ^^^^^^^^^^^^^^ -->
<!-- 日付を出力する際の表示形式を設定出来ます。 -->
<!-- サポートしている表示形式は以下の通りです。 -->
<!-- ========== ============= -->
<!-- 表示形式   出力内容 -->
<!-- ========== ============= -->
<!-- 日         24日 -->
<!-- 月         4月 -->
<!-- 年         2024年 -->
<!-- 月日       4月24日 -->
<!-- MM/DD      4/24 -->
<!-- 年月日     2024年4月24日 -->
<!-- YYYY/MM/DD 2024/04/24 -->
<!-- ========== ============= -->
<!-- .. warning:: -->
<!-- - 日付型を直接出力する場合、ユーザープロフィールが協定世界時（UTC）で表示されるため日本時間(JST)と9時間ずれて表示されます。 -->
<!-- - 日本時間で表示したい場合は9時間（32400秒）を足してください。 -->
<!-- - 例えば ``first_launch_date`` を日本時間で、``MM/DD`` の形式で表示したい場合は以下のように記述します。 -->
<!-- - ``{{ user_profile['first_launch_date'] | date: '%s' | plus: 32400 | date: '%-m/%d' }}`` -->

---

## 変数の挿入

### 概要

プッシュ通知やイベント起点プッシュ通知、アプリ内メッセージ等のReproのキャンペーンでユーザープロフィールやイベントプロパティを変数として挿入し、メッセージの内容をパーソナライズできます。
 
パーソナライズされたメッセージを配信することで、プッシュ通知の開封率や、メッセージのクリック率、CVRの改善が期待できます。
 

##### WARNING
Reproでの変数挿入は、Liquidというテンプレート言語を利用しています。Liquid記法を利用した条件分岐などの複雑なロジックについては、 [Liquidによるパーソナライズ](https://docs.repro.io/ja/dashboard/campaign/liquid-personalization.md) をご参照のうえ、十分にテストを行ってからご利用ください。意図しないメッセージの表示や配信が行われる可能性があります。

### 具体的なユースケース例

- ユーザー名を差し込んだパーソナライズ
  - 例: **Tanaka**様への特別オファー✨
- 年代や性別を元にメッセージをパーソナライズ
  - 例:20代以下男性、20代以下女性、30代男性、30代女性、40代以上男性、40代以上女性でメッセージの文言を分けて配信する

このほかの具体的なユースケース例はサポートサイトの[Liquidを利用したサンプル集](https://support.repro.io/hc/ja/articles/35664363059737)をご覧ください。

### チャネルごとの対応状況

各チャネルの変数の挿入が可能な項目は以下になります。

#### プッシュ通知

- 挿入できる値
  - ユーザープロフィール
- 挿入可能な項目
  - タイトル
  - 本文
  - リッチ通知メディア(URL)
  - ディープリンク
  - カスタム（JSON）

#### イベント起点プッシュ通知

- 挿入できる値
  - ユーザープロフィール
  - 配信トリガー実行時のイベントプロパティ
- 挿入可能な項目
  - タイトル
  - 本文
  - リッチ通知メディア(URL)
  - ディープリンク
  - カスタム（JSON）

#### アプリ内メッセージ

- 挿入できる値
  - ユーザープロフィール
  - [インセンティブコード](https://docs.repro.io/ja/dashboard/campaign/incentive-code-management.md)
- 挿入可能な項目
  - 見出し
  - 本文
  - アクションボタン
  - ディープリンクもしくはURL
  - カスタム（HTML）

#### HTMLアプリ内メッセージ

- 挿入できる値
  - ユーザープロフィール
  - [インセンティブコード](https://docs.repro.io/ja/dashboard/campaign/incentive-code-management.md)
- 挿入可能な項目
  - 見出し
  - 本文
  - アクションボタン
  - ディープリンクもしくはURL
  - カスタム（HTML）

#### Webメッセージ

- 挿入できる値
  - ユーザープロフィール
  - [インセンティブコード](https://docs.repro.io/ja/dashboard/campaign/incentive-code-management.md)
- 挿入可能な項目
  - 見出し
  - 本文
  - ボタン
  - ディープリンクもしくはURL
  - カスタム（HTML）

### プッシュ通知でのパーソナライズ施策の作成

#### プッシュ通知での変数の挿入の注意事項

##### WARNING
- 公開する前に**必ずテスター向けにテスト配信をして、意図した配信がされるか確認**しましょう
  - パーソナライズされたプッシュ通知の配信は既存のキャンペーンとは異なり、複雑なロジックを組むことができます。
  - 結果的に通常のキャンペーン以上に**意図しない配信やメッセージの表示の事故が発生する可能性**があります
- 配信対象を鑑みて、空の状態で配信されるようなユーザーがいないか確認してください。
- プッシュ通知で利用する場合プッシュAPI、バルクプッシュAPIとの併用できません。

### プッシュ通知作成

パーソナライズ施策の例として、今月末にポイントが失効するユーザーに具体的に失効するポイント数を差し込んでパーソナライズする施策を作成します。

#### キャンペーン情報を入力

キャンペーン情報は、既存のキャンペーン同様に入力します。





##### 注意事項

- `通知をニュースフィードとして使う`
  にチェックを入れると、変数の挿入は利用できません

#### メッセージ内容を入力

##### タイトルにパーソナライズするユーザープロフィールを入力する

タイトルを `今月末に800ポイントが失効します👀` というパーソナライズ配信をしたい場合、 `今月末に` までを入力し、入力フォーム下部にある `変数の挿入` ボタンをクリックします。



##### 変数差し込みUIを利用して変数を挿入する

##### WARNING
- 変数差し込みUIを利用して挿入したLiquidを編集しないようにしてください。
  : - Liquidを編集して誤った構文となった場合、意図しないメッセージの表示や配信が行われる可能性があります



変数を挿入するためのモーダルが表示されるので、変数のタイプで `ユーザープロフィール` を選択します。



変数のキーの項目をクリックし、差し込み対象のユーザープロフィール一覧が表示されるので、差し込みたい変数名を検索しクリックします。
今回は `整数型` のユーザープロフィールである `失効ポイント数` を指定します。



##### 変数差し込みUIに条件を設定する

**デフォルト値の入力について**

デフォルト値を設定することで変数のキーに指定したユーザープロフィールがセットされていないユーザーや空文字が登録されているユーザーにはデフォルト値が差し込まれ配信されます。
今回は**配信対象設定**で、`失効ポイント数` が `800以上`
という条件を入れるのでデフォルト値は設定しませんが、基本的には**デフォルト値の設定を推奨します**。

### 配信対象設定



配信対象設定として、 `失効ポイント数` が `800以上` というフィルターをセットします。

##### WARNING
- Liquidのタグにデフォルト値を指定しない場合は、必ずユーザープロフィールが登録されている条件を設定する必要があります
  - この例では、「`失効ポイント数`が登録されている」と登録する必要があります
- デフォルト値を設定せず、[登録されている]ことも配信対象と設定しなかった場合は
  `{{user_profile['失効ポイント数']}}`
  の箇所が**空になった状態で配信**されます
  - 今月末にポイント失効します👀
    という内容が配信されます（配信対象に登録有無を含めていないため、失効ポイントが存在しないユーザーにも配信される可能性があります）

### 下書き保存したメッセージを複製し、テスター向けにテスト配信を行う



配信対象設定が完了したらメッセージを下書き保存し、下書きメッセージを複製して配信対象をテスターに変更した上でテスト配信します。この際、テスターに `失効ポイント数` のユーザープロフィールがセットされていない場合、空で配信されてしまうので必ずユーザープロフィールがセットされていることを確認して配信してください。

### 下書きメッセージを公開

テスト配信で変数が問題なく差し込まれることを確認したら、下書きからメッセージを公開してメッセージの作成は完了です。

### アプリ内メッセージ、Webメッセージでのパーソナライズ施策の作成

#### アプリ内メッセージ、WebメッセージでのLiquid利用時の注意事項

##### WARNING
- 公開する前に**必ずテスターオーディエンスなどを用いてテストを行い、意図した表示がされるか確認**しましょう
  - パーソナライズされたメッセージの表示は既存のキャンペーンとは異なり、複雑なロジックを組むことができます。
  - 結果的に通常のキャンペーン以上に**意図しないメッセージの表示の事故が発生する可能性**があります
- **必ずユーザープロフィール、インセンティブコードのいずれかを差し込んだLiquidを記述してください。** ユーザープロフィール、インセンティブコードの差し込みがない場合、**Liquid構文がそのまま配信されます。**
- ユーザープロフィール設定でユーザープロフィールの型を確認したり、配信対象設定でよく登録されている値や配信対象数を確認して意図したユーザープロフィールがセットされているか確認します
  - サポートサイト「FAQ：[ユーザープロフィールの実装後、ユーザーに設定できているか確認する方法はありますか？](https://support.repro.io/hc/ja/articles/23586392155161)」も参考にしてください。
- 配信対象を鑑みて、空の状態で配信されるようなユーザーがいないか確認してください。

### メッセージ作成

パーソナライズ施策の例として、今月末にポイントが失効するユーザーに具体的に失効するポイント数を差し込んでパーソナライズする施策を作成します。

#### キャンペーン情報を入力

キャンペーン情報は、既存のキャンペーン同様に入力します。





##### 注意事項

- `通知をニュースフィードとして使う`
  にチェックを入れると、変数の挿入は利用できません

#### メッセージ内容を入力

##### 本文にパーソナライズするユーザープロフィールを入力する

本文が `今月末に800ポイントが失効します👀` というパーソナライズメッセージを表示したい場合、 `今月末に` までを入力し、入力フォーム下部にある `変数の挿入` ボタンをクリックします。



##### 変数差し込みUIを利用して変数を挿入する

##### WARNING
- 変数差し込みUIを利用して挿入したLiquidを編集しないようにしてください。
  : - Liquidを編集して誤った構文となった場合、意図しないメッセージの表示や配信が行われる可能性があります



変数を挿入するためのモーダルが表示されるので、変数のタイプで `ユーザープロフィール` を選択します。



変数のキーの項目をクリックし、差し込み対象のユーザープロフィール一覧が表示されるので、差し込みたい変数名を検索しクリックします。
今回は `整数型` のユーザープロフィールである `失効ポイント数` を指定します。



変数のキーを指定するとキーの型に対応した設定項目が表示されます。

##### NOTE
- HTMLアプリ内メッセージ、 Webメッセージでは、利用できる変数に制限があります

##### デフォルト値の入力について

デフォルト値を設定することで変数のキーに指定したユーザープロフィールがセットされていないユーザーや空文字が登録されているユーザーにはデフォルト値が差し込まれ配信されます。
基本的には**デフォルト値の設定を推奨します**。

---

## インセンティブコード管理機能

##### NOTE
インセンティブコード管理機能を利用するには別途申し込みが必要です。ご希望の場合は担当CSにご連絡ください。

インセンティブコード管理機能を使用することで、ギフトコード・ポイントの受け取りURL・文字列等を、特定のイベントが発生したユーザー個別に割り当てることができます。Reproの持つイベント情報を基に配布処理や在庫管理を行なうことができるため、ユーザーへのインセンティブ配布を低コストで実現することができます。

### 具体的なユースケース例

* **購入者に次回購入時に使えるクーポンを配布する**
  : - キャンペーン期間内に購入を行ったことをトリガーとして、クーポン受取URLを埋め込んだアプリ内メッセージを次回アプリ起動時に表示させ、2回目の購入を促します。
* **（サブスクリプション）有料入会促進**
  : - 無料コンテンツを利用しているユーザーに特別オファーとしてクーポン受取URLを埋め込んだメッセージを表示し、有料入会を促進します。

##### NOTE
上記はユーザーが特定のURLをクリックするとクーポンやポイントの獲得ができる仕様のサービスを想定したユースケースとなります。

### インセンティブコードのインポート

インセンティブコード管理機能を使用してインセンティブコードを配布するためには、まずインセンティブコードをReproの管理画面よりインポートする必要があります。

1. マーケティング > インセンティブコード > インセンティブコードリスト
   を開きます


1. 「新規作成」ボタンをクリックして、新しいインセンティブコードリストを作成します



ここでの設定項目については以下の通りです。

| 項目 | 説明 |
| --- | --- |
| インセンティブコードリストの名前 | 区別しやすい任意の名前を設定してください |
| CSVファイルを選択 | 次の項目で説明する書式のCSVファイルを指定してください |
| 通知設定 | インセンティブコードリスト内で割り当て可能なインセンティブコードの残数が指定された値以下になった場合、毎朝9時にメールにてお知らせします。管理画面に登録されている方全員が送信の対象となります。 |
1. 「保存」をクリックし、インセンティブコードリストを保存します。

##### WARNING
- アップロードされたCSV内でインセンティブコードに重複がある場合、取り込み処理は失敗します。
- インポートしたインセンティブコードは、オーナーまたは管理者にのみ表示され、それ以外のメンバーにはマスクされて表示されます

#### CSVフォーマット

CSVはヘッダーを含めた下記のような内容です。

```
incentive_code,expire_date,point,provider
myapp://samplecoupon/abc,2025-07-18T16:20:20+09:00,150,"sample corp"
```

各カラムは以下の意味を持ちます。

| カラム | 説明 | 例 |
| --- | --- | --- |
| incentive_code | 配布されるインセンティブコードです。文字列を使用することができます。URLやDeepLink、クーポンコードとしての任意の文字列を記載してください。 | `myapp://samplecoupon/abc` や `coupon-code-abc` など |
| expire_date | そのインセンティブコードの期限がいつまでなのかを表します。書式は `%Y-%m-%dT%H:%M:%S%z` となります。 | `2025-07-18T16:20:20+09:00` |
| point | インセンティブコードによって付与されるポイントを表す整数値です。 | 150 |
| provider | インセンティブコードの発行主体を区別するための識別子です。 | `sample corp` |

##### WARNING
* 割り当てイベントが発生したタイミングにおいて、expire_dateがその時刻から30日間有効なインセンティブコードが割り当てられます
* **expire_dateまでが30日間未満となったインセンティブコードは自動的に「期限切れ」となり、割当が行われなくなります。有効期限を十分に確保したうえでインポートを行ってください。**
* インセンティブコードはプロジェクト内で一意である必要があります。
* CSVファイルの末尾は単一の改行文字である必要があります。

### 割り当てルールについて

マーケティング > インセンティブコード > 割り当てルール
より、インセンティブコードの割り当てルールを作成することができます。
割り当てルールで定めた条件を満たしたユーザーにインセンティブコードリストに追加したインセンティブコードが順次割り当てられます。



##### NOTE
インセンティブコードリストが存在しない場合、割り当てルールを作成することはできません。

#### 割り当てルール作成画面



ここでの設定項目については以下の通りです。

| 項目 | 説明 |
| --- | --- |
| 名前 | 割り当てルールに対して、区別しやすい任意の名前を設定してください |
| 配信対象設定 | インセンティブコードの割り当て対象となるユーザーを設定してください |
| トリガー | どのようなイベントが発生したらインセンティブコードを割り当てるかを設定してください |
| 1ユーザーに対する割り当て回数 | 1ユーザーに最大いくつインセンティブコードを割り当てるか設定してください |
| 期間 | 割り当てルールが有効な期間を設定してください |
| インセンティブコードリスト | どのリストからインセンティブコードを割り当てるかの設定をしてください |

##### WARNING
アプリ内メッセージ・Webメッセージでインセンティブコードを配布する場合、「1ユーザーに対する割り当て回数」を2回以上に設定しても、表示されるインセンティブコードは常に1回目に割り当てが行われたインセンティブコードとなります。

### アプリ内メッセージ作成

アプリ内メッセージでは、 `{{incentive_code}}` と入力した部分が、メッセージが配信されたユーザーに対して割り当てられたインセンティブコードに置き換えられて表示されます。



この例では、インセンティブコードとしてアクセス可能なURLを使用している場合に「クーポンをGETする」を押すとURLに遷移してインセンティブを受けとれるようなメッセージを作成しています。

##### NOTE
* 割り当てルールで定めた条件を満たしたユーザーには「（割り当てルールの名称）_割当完了」というイベントが自動的に発火されます。
* インセンティブコードを表示するメッセージは、配信対象設定フィルターに割り当て完了イベントを含める必要があります

### Webメッセージ作成

Webメッセージでは、 `{{incentive_code}}` と入力した部分が、メッセージが配信されたユーザーに対して割り当てられたインセンティブコードに置き換えられて表示されます。



この例では、インセンティブコードとしてアクセス可能なURLを使用している場合に「クーポンをGETする」を押すとURLに遷移してインセンティブを受けとれるようなメッセージを作成しています。

##### NOTE
* 割り当てルールで定めた条件を満たしたユーザーには「（割り当てルールの名称）_割当完了」というイベントが自動的に発火されます。
* インセンティブコードを表示するメッセージは、配信対象設定フィルターに割り当て完了イベントを含める必要があります

---

## プッシュ通知

プッシュ通知とはユーザーがアプリを起動していなくても通知を送れる機能です。
そのため、リテンション率の改善や休眠ユーザーの復帰などの活用に適しています。


Reproではプッシュ通知を簡単に送ることができます。
 
既存ユーザーへの一括配信はもちろん、実行したイベントやユーザープロフィールに登録されている情報にもとづいてセグメントした配信対象に配信することもできます。
 
また１回だけの配信ではなく、指定した時刻に毎日/毎週プッシュ通知を配信する定期配信機能で自動的なマーケティング施策を行うことができます。
 

### プッシュ通知を有効にする

プッシュ通知を配信する前に、プッシュ通知を使うための設定が必要です。
設定は環境により変わりますので、ご自身の環境に合わせて設定をお願いします。

- iOS
  - [APNs証明書の設定 (iOS)](https://docs.repro.io/ja/dev/sdk/push-notification/setup-ios.md)
  - [プッシュ通知の設定](https://docs.repro.io/ja/dev/sdk/push-notification/ios.md)
- Android
  - [FCMの設定 (Android)](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md)
  - [プッシュ通知の設定](https://docs.repro.io/ja/dev/sdk/push-notification/android.md)
- Unity
  - [プッシュ通知の設定](https://docs.repro.io/ja/dev/sdk/push-notification/unity.md)
- Cordova
  - [プッシュ通知の設定](https://docs.repro.io/ja/dev/sdk/push-notification/cordova.md)
- Monaca
  - [プッシュ通知の設定](https://docs.repro.io/ja/dev/sdk/push-notification/monaca.md)
- Cocos2d-x
  - [プッシュ通知の設定](https://docs.repro.io/ja/dev/sdk/push-notification/cocos2d-x.md)
- React Native
  - [プッシュ通知の設定 (iOS)](https://docs.repro.io/ja/dev/sdk/push-notification/react-native.md)
  - [プッシュ通知の設定 (Android)](https://docs.repro.io/ja/dev/sdk/push-notification/android.md)
- Flutter
  - [プッシュ通知の設定 (iOS)](https://docs.repro.io/ja/dev/sdk/push-notification/flutter.md)
  - [プッシュ通知の設定 (Android)](https://docs.repro.io/ja/dev/sdk/push-notification/flutter.md)



### プッシュ通知作成画面

それではプッシュ通知を作成します。[マーケティング] > [プッシュ通知]をクリックします。



プッシュ通知一覧画面が表示されるので、[新規作成] をクリックします。



プッシュ通知作成画面が表示されます。



次に、それぞれの設定項目を説明します。



#### キャンペーン



| 項目 | 説明 |
| --- | --- |
| キャンペーン名 | キャンペーン名を入力します。プッシュ通知の一覧に表示されます。 |
| キャンペーンのゴール(任意) | キャンペーンのゴールとなるイベントを選択します。集計されるユーザーはプッシュ通知を開封してから1時間以内にこのイベントを実施したユーザーです。 詳細は [効果測定（A/Bテスト）](#push-measurement) をご覧ください。 |
| キャンペーンの狙いと実施後の結果(任意) | キャンペーンの狙いと実施後の結果を入力します。効果測定の画面でメモとして確認できます。 |
| 通知をニュースフィードとして使う | チェックを入れると、作成したキャンペーンをニュースフィードとして利用できます。 ニュースフィードとは、**ユーザーごとのキャンペーンの配信履歴** のことです。この履歴を利用することで、今までに送ったキャンペーンの履歴をアプリ内のお知らせ欄で表示するといったことが可能です。 ご利用に際しては [ニュースフィード](https://docs.repro.io/ja/dashboard/campaign/newsfeed.md) をご覧ください。 |

#### メッセージ

メッセージの設定項目は、選択した「プッシュ通知の種類」により2パターン存在します。それぞれ説明します。



##### メッセージ(プッシュ通知「スタンダード」)



| 項目 | 説明 |
| --- | --- |
| パターン | パターンを選択します。 [追加]をクリックするとパターンの追加と複製ができます。 パターンはA/Bテストを実施する際に利用します。詳細は [使用事例：A/Bテストの実装](#push-ab) をご覧ください。 |
| タイトル(任意) | メッセージのタイトルを入力します。未入力の場合はアプリ名が表示されます。 **※「通知をニュースフィードとして使う」にチェックを入れた場合** タイトルは必須入力です。 |
| 本文 | 一般的な形式のメッセージを簡単に作成できます。 |
| リッチ通知メディア(任意) | メッセージに画像、動画、音声のメディアを添付することができます。 **画像** ファイルフォーマット: JPEG、PNG、GIF ファイルサイズ：最大1MB 画像サイズ： アスペクト比: 2:1 横幅: 1280px 以上 3000px 以下 アニメーションGIFを表示できるのはiOSのみです。 画像ファイルをアップロードするか、または、自社サーバー等でホスティングしている画像ファイルのURLを指定してください。 **動画** 自社サーバー等でホスティングしているMP4ファイルのURLを指定してください。 動画を配信できるのはiOSのみです。 **音声** 自社サーバー等でホスティングしているMP3ファイルのURLを指定してください。 音声を配信できるのはiOSのみです。 **※URL記入時の注意点** `https://` で始まるURLのみ指定することができます。 `http://` で始まるURLはサポートしておりません。 |
| ディープリンクもしくはURL(任意) | ディープリンクもしくはURLを設定すると、エンドユーザーが通知をタップしたときにそのアドレスをSDKが自動的に開きます。 ディープリンクを指定した場合：アプリ内の特定のページを開きます（アプリ側の実装が必要です）。 URLを指定した場合：ブラウザでWebページを開きます。 未指定の場合は、アプリを通常起動します。 最大文字列長は1000文字です。 **ディープリンクについて** ディープリンクは以下3種類のディープリンクに対応しています。 ユニバーサルリンク アプリリンク カスタムURL Scheme ユニバーサルリンクとアプリリンクを指定したい場合は、 [ディープリンクに、ユニバーサルリンク（iOS）やアプリリンク（Android）を利用する場合](#clear-badge-setting) をご確認ください。 |
| 追加設定 | **バッジを表示する** チェックを入れると通知を受信したことを示すバッジを表示します。表示できるバッジの数値は1のみとなります。バッジの数値をカスタマイズしたい場合は、カスタム（JSON）形式を利用してください。また、一度表示されたバッジを消すには [バッジを消す処理の実装](https://docs.repro.io/ja/dev/sdk/push-notification/ios.md#clear-badge) が必要です。 **プッシュ通知のサウンドを変更する** チェックを入れると通知にカスタムサウンドが利用できます。 チェックを入れると表示されるテキストフィールドにサウンドファイル名を入力してください。ファイル名が入力されていない場合、iOSのシステムサウンドが使用されます。 |
| 通知プレビュー | 「iOS」「Android」のプレビューを選択します。 |
| プレビュー | 「通知プレビュー」で選択したプレビューを表示します。 |



##### ディープリンクに、ユニバーサルリンク（iOS）やアプリリンク（Android）を利用する場合

URLの指定先に、ユニバーサルリンク（iOS）やアプリリンク（Android）の利用も可能です。
利用する場合は、下記の対応を行ってください。

**Repro SDKを、iOS SDK 5.9.0/Android SDK 5.7.0以上にアップデートする**

バージョンが古い場合、下記を参考に最新バージョンにアップデートしてください。

- iOSの場合：[iOS SDK 更新手順](https://docs.repro.io/ja/releases/sdk/ios/upgrade.md)
- Androidの場合：[Android SDK 更新手順](https://docs.repro.io/ja/releases/sdk/android/upgrade.md)

**SDKにユニバーサルリンク/アプリリンクに対する処理を実装する**

アプリにてユニバーサルリンク/アプリリンクの処理を追加するには、実装する必要があります。下記ドキュメントを参考に実装をお願いします。

- iOSの場合： [オプション：ユニバーサルリンクを使用する](/ja/dev/sdk/push-notification/ios.html#id5) を参考に設定してください
- Androidの場合： [オプション：アプリリンクを使用する](/ja/dev/sdk/push-notification/android.html#id8) を参考に設定してください

上記実装が完了しているアプリでは、「ディープリンクもしくはURL」フィールドに、ユニバーサルリンク/アプリリンクを記載することで、遷移先にユニバーサルリンクやアプリリンクを利用できるようになります。

##### NOTE
詳細については、[ReproApp 機能アップデート｜プッシュ通知やアプリ内メッセージに利用できるリンクの種類が増えました](https://reproio.zendesk.com/hc/ja/articles/8671005707033) をご確認ください。



##### リッチ通知メディアの注意点

リッチ通知メディア利用の際は、下記に注意いただきご利用ください。

##### NOTE
- メディアを添付できるのは、iOS 10以上、Android 4.1以上です。それよりバージョンが低いOSの場合、メッセージのみの通知が配信されます。
- iOS: メディアを添付してプッシュ通知を配信する際は、メディアを表示するための追加の準備が必要です。詳しくは [オプション：リッチ通知の受信準備](https://docs.repro.io/ja/dev/sdk/push-notification/ios.md#ios-receiving-rich-notification) をご覧ください。
- Android: メディアを配信する場合、メッセージの本文が一行を超えると省略される場合があります。

##### WARNING
- メディアはプッシュ通知を受信した際にダウンロードされますが、ダウンロードの時間に制限があります。
  - iOS: メディアのダウンロードに30秒以上かかった場合、テキストのみの通知が表示されます。
  - Android: メディアをダウンロードに5秒以上かかった場合、通知そのものが表示されなくなります。



##### メッセージ(プッシュ通知「カスタム(JSON)」)

バッジやサイレントプッシュ通知、カスタムペイロードなど、デフォルトのメッセージでは対応していない内容のメッセージを配信する場合はカスタム (JSON) 形式を選択してください。



| 項目 | 説明 |
| --- | --- |
| カスタムペイロード(iOS向け) | iOS向けのJSONを入力します。 |
| カスタムペイロード(Android向け) | Android向けのJSONを入力します。 |

##### NOTE
- **Android**: カスタム (JSON) 形式のメッセージをアプリケーションで受信するには、FirebaseMessagingServiceのonMessageReceivedを実装する必要があります。詳しくは、開発ガイド > プッシュ通知（Android）の「[オプション：プッシュ通知受信時の動作をカスタマイズする](https://docs.repro.io/ja/dev/sdk/push-notification/android.md#customize-receiver)」をご確認ください。
- **Android**: Android向けの JSON で "data" の中に含める key-value については、文字列のみ指定することができます。詳細については [FCMのドキュメント](https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages) をご確認ください。

##### 参考：アイコンをカスタマイズする

プレビューに表示されるアイコンは [設定] > [プロジェクト設定] > [全般]に設定されているものです。実機上では使用されません。

* **iOS**: アプリのデフォルトのアイコンが使われます。
* **Android**: 通知に使われるアイコンを変更できます。詳細は [アイコンと背景色のカスタマイズ](https://docs.repro.io/ja/dev/sdk/push-notification/android.md#push-android-customize-icon) をご覧ください。

##### NOTE
「変数の挿入」ボタンがある項目には、Liquid記法によってユーザープロフィールの値を挿入することができます。詳細は [Liquidによるパーソナライズ](https://docs.repro.io/ja/dashboard/campaign/liquid-personalization.md) をご覧ください。

#### 配信対象者を各パターンに振り分ける

「[配信対象設定](#push-measurement-filter)」 で設定した配信対象者をコントロールグループと、パターン1に振り分けます。

コントロールグループ(統制群)とは、 **プッシュ通知を配信しない対象者** を指します。
 
キャンペーン自体の効果を計測するために、 **プッシュ通知を配信するユーザー** と **プッシュ通知を配信しないユーザー** で効果を比較できます。
 


| 項目 | 説明 |
| --- | --- |
| コントロールグループ | 0% ~ 99%の範囲で指定できます。 |
| パターン 1 | 1% ~ 100%の範囲で指定できます。 |
| 均等に振り分ける | クリックすると、コントロールグループとパターン1を **50%** ずつ均等に振り分けます。 |
| 均等に振り分ける(コントロールグループなし) | クリックすると、コントロールグループを **0%**、パターン1を **100%** に振り分けます。 |

例えば、配信条件を **既存ユーザー** とした場合に、コントロールグループを **20%** 、 パターン1を **80%** に設定すると、既存ユーザーの中からランダムで抽出された **約80%** のユーザーにメッセージが配信され、残りの **約20%** のユーザーにはメッセージは配信されません。

##### NOTE
- 整数のみ設定出来ます。
- 振り分け設定は新規作成時のみ行うことが出来ます。
- 配信数の規模により、設定した割合と実際の配信数が乖離することがあります。

パターンを3つ以上に増やした状態の設定方法は、「[使用事例：A/Bテストの実装](#push-ab)」をご覧ください。

#### 配信設定



配信の種類として、「時刻を指定して配信」と「プッシュAPIを利用して配信」の２パターン存在します。それぞれ説明します。

##### 配信設定(時刻を指定して配信)

管理画面からプッシュ通知を配信する場合は「時刻を指定して配信」を選択してください。配信時刻を指定できます。



| 項目 | 説明 |
| --- | --- |
| 配信の詳細設定 | 「指定された時刻に配信」「プッシュ通知の公開後すぐに配信を開始」のいずれかを選択します。 |
| 配信時刻 | 「指定された時刻に配信」を選択した場合のみ指定できます。 配信回数と配信時間を指定します。 |
| 追加設定 | チェックを入れると通知を一定間隔に分割して配信します。 |

配信時刻の設定例は下記のとおりです。

| タイプ | 機能 | 使い方 |
| --- | --- | --- |
| 1回 | 作成したらすぐに1回だけ配信 | **プッシュ通知の公開後すぐに配信を開始** を選択してください。 |
| 1回 | 指定した時刻に1回だけ配信 | **指定された時刻に配信** を選択してください。 配信時刻に「通知を **一度だけ** **2016-05-23** **10**:**00** に配信する」のように設定してください。 |
| 定期配信 | 指定された時刻に毎日通知を配信 | **指定された時刻に配信** を選択してください。 配信時刻を「通知を **毎日** **10**:**00** に配信する 配信開始 **2016-05-23** 配信終了 **2016-06-23**」のように設定してください。 終了日を指定しない場合は **終了日を指定しない** にチェックを入れて下さい。 |
| 定期配信 | 指定された時刻に毎週通知を配信 | **指定された時刻に配信** を選択してください。 配信時刻を「通知を **毎週** **月曜日** **10**:**00** に配信する 配信開始 **2016-05-23** 配信終了 **2016-06-23**」のように設定してください。 終了日を指定しない場合は **終了日を指定しない** にチェックを入れて下さい。 |
| 定期配信 | 指定された時刻に毎月通知を配信 | **指定された時刻に配信** を選択してください。 配信時刻を「通知を **毎月** **1日** **10**:**00** に配信する 配信開始 **2016-05-23** 配信終了 **2016-06-23**」のように設定してください。 終了日を指定しない場合は **終了日を指定しない** にチェックを入れて下さい。 |

##### 配信設定(プッシュAPIを利用して配信)

プッシュAPIを利用してプッシュ通知を配信できます。APIトークンはプッシュ通知を保存した後に生成されます。
プッシュAPIの詳細な設定方法は [開発ガイド] > [[プッシュAPI](https://docs.repro.io/ja/dev/push-api/index.md)] をご覧ください。





#### 配信対象設定



イベントやユーザープロフィール、全ユーザーといったセグメンテーションフィルターをつかって、配信対象となるユーザーを指定できます。
各フィルターは **and** 、 **and not** 、 **or** を使って、最大5個まで組み合わせられます。

| 項目 | 説明 |
| --- | --- |
| and | 指定した条件を全て満たすユーザーが対象になります。 |
| and not | 指定した条件にあてはまるユーザーが対象から除外されます。 |
| or | 指定した複数の条件のどれかにあてはまるユーザーが対象になります。 |

##### NOTE
配信対象設定は、配信設定で「時刻を指定して配信」を選択した場合のみ設定できます。

##### フィルター

利用できるフィルターは以下の通りです。



| 項目 | 説明 | 注意事項 |
| --- | --- | --- |
| オーディエンス | [オーディエンス](https://docs.repro.io/ja/dashboard/campaign/audience.md) で作成したセグメンテーションを利用することができます。 | - フィルターオーディエンス: 他のフィルタリング条件と組み合わせることはできません。 - インポートオーディエンス: 他のフィルタリング条件と組み合わせることができます。 - Smart Audience™: 他のフィルタリング条件と組み合わせることができます。 |
| イベント | [イベント](https://docs.repro.io/ja/dev/sdk/tracking.md) を実行したユーザーをセグメンテーションすることができます。実行した期間や回数を指定することができます。 |  |
| イベントプロパティ | [イベント](https://docs.repro.io/ja/dev/sdk/tracking.md) を実行したユーザーのうち、実行されたイベントに付帯するプロパティにもとづいてユーザーをセグメンテーションすることができます。 プロパティの名前や値、実行した期間や回数を指定することができます。 |  |
| ユーザープロフィール | [ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md) に登録されている情報にもとづいてユーザーをセグメンテーションすることができます。SDKでプロフィールの型に数値を指定している場合、「以上、以下、より大きい、より小さい」などをつかって、値を比較する条件を指定できます。文字を指定している場合、「一致する、一致しない、含む」などをつかって、条件を指定できます。日付を指定している場合、「◯日前以前、◯日前〜▢日前、特定日以前」などをつかって、条件を指定できます。 日付の指定については、[サポートサイトのFAQ](https://support.repro.io/hc/ja/articles/23886462974489) に詳細な説明がありますので、こちらも参考にしてください。 |  |
| 既存ユーザー | Reproに登録されたすべてのユーザーが対象となります。既存ユーザーから特定条件を満たすユーザーを除外する場合は、 **and not** でフィルターを追加してください。 |  |

##### フィルタ利用例

フィルタの利用例をご紹介します。

- 例1：3日前にアプリを使用して、その後2日間アプリを使っていないユーザーへ配信する場合


- 例2：性別が女性で直近3日以内にイベントAかイベントBのどちらかを実行したユーザーへ配信する場合



#### 下書きで保存、非公開、公開ボタン



| 項目 | 説明 |
| --- | --- |
| 下書きで保存 | 下書きで保存をクリックすると、作成したプッシュ通知が配信されることなく保存されます。 キャンペーンの必須項目をすべて記入していない状態など、キャンペーンの作成途中で作成を終えたい場合は、 **下書きで保存** をクリックしてください。 下書きで保存をした場合は、後からキャンペーンのゴールやメッセージのパターンを変更することができます。 下書き状態のキャンペーンはプッシュ通知一覧画面の下書きタブから選択できます。 |
| 非公開 | 作成したプッシュ通知を非公開にします。非公開の場合プッシュ通知は配信されません。 |
| 公開 | 作成したプッシュ通知を公開にします。公開すると、指定された日時にプッシュ通知の配信処理が開始されます。 |

##### NOTE
- 公開もしくは非公開をクリックする前に、設定したキャンペーンの内容を注意深くチェックしてください。キャンペーンを公開、非公開で登録後からキャンペーンのゴール、メッセージのパターン が **変更できなくなります。**
- 確認後、キャンペーンを公開する準備が整っていれば、 **公開** を、そうでない場合は **非公開** をクリックしてください。

##### WARNING
- 処理負荷の増大、システム障害等が原因でプッシュ通知の配信開始が配信予定時刻より30分以上遅延した場合、想定していない時間での通知を防止するため、配信処理は自動停止します。
- プッシュ通知の配信が中断された場合、メールで通知が届きます。プッシュ通知の配信が中断されるケースは以下のとおりです。
  - 無効なAPNs証明書、無効なFCM/GCM API Keyが設定されているとき
  - データポイント使用量が上限に達している場合
  - 処理負荷の増大、システム障害等が原因で配信が30分以上遅延した場合
- 配信が中断した場合、配信結果の配信数は0になります。
- FCM にはデフォルトで 60万件/分 の割り当てが設定されており、配信速度が制限されております。この割り当てを超えて配信する必要がある場合はFCMの公式ドキュメントで要件を確認の上、FCMに割り当ての増加をリクエストしてください。

  [https://firebase.google.com/docs/cloud-messaging/throttling-and-quotas?hl=ja](https://firebase.google.com/docs/cloud-messaging/throttling-and-quotas?hl=ja)

### プッシュ通知配信結果画面

プッシュ通知の結果を確認することができます。

[マーケティング] > [プッシュ通知]をクリックし、プッシュ通知一覧画面より表示されたキャンペーン名をクリックします。





#### 配信結果

開封数やコンバージョン数といったプッシュ通知の効果を確認できます。



| 項目 | 説明 |
| --- | --- |
| 配信数 | プッシュ通知許諾がONのユーザーに対する配信のうち、ReproサーバーからAPNsやFCMへのリクエストが正常に受理された数です。日次でユニークユーザー数を集計します。 |
| 開封数 | 開封したユーザー数を日次で集計し、合計した数です。開封数にはみなし開封数と直接開封数が含まれます。 **みなし開封数** 配信から1時間以内にアプリを起動したユーザーの数です。 **直接開封数** 通知を直接タップしてアプリを起動したユーザーの数です。 |
| コンバージョン数 | プッシュ通知の「開封」から1時間以内に、作成画面で指定したゴールを達成したユーザーの数を日次で集計し、合計した数です。 この「開封」には、「みなし開封」・「直接開封」の両方が含まれます。 |
| コンバージョン率 | コンバージョン数 / 配信数 です。 |
| 結果の推移 | キャンペーン実施期間中の配信数、開封数、コンバージョン数を日次で集計した結果をグラフとして出力しています。計測単位はユーザーです。 |

##### NOTE
配信時刻の1時間以内に通知をタップしアプリを起動した場合、直接開封のみに計上されみなし開封には計上されません



### 使用事例：A/Bテストの実装

次に、実際にプッシュ通知を使用した例を紹介します。今回はA/Bテストの実装方法を説明します。

A/Bテストとは、配信対象に指定したユーザーに複数のパターンのメッセージを均等に出し分けることで、どのようなメッセージを配信すれば開封率やコンバージョン率が向上するのかを検証することができる機能です。

定期配信と併用する場合は、最も効果の高かったメッセージを勝ちパターンとして指定することができます。

#### メッセージを作成する

まずはメッセージを作成します。メッセージのパターンを2個以上作成することで、A/Bテストを行うことができます。

プッシュ通知の作成画面より、パターンの[追加]をクリックしてください。



[追加]をクリックすると、「パターン１を複製」と「新規作成」が表示されます。ご希望の作成方法をクリックします。



| 項目 | 説明 |
| --- | --- |
| パターン１を複製 | パターン１と同様の内容を複製します。 |
| 新規作成 | 新たにメッセージ内容を作成します。 |

「パターン２」が作成されます。



「パターン２」の右横の「×」をクリックするとパターンが削除されます。

##### NOTE
- メッセージは最大4パターンまで追加することができます。
- [プッシュ API](https://docs.repro.io/ja/dev/push-api/index.md) とは併用できません。
- パターンの追加や削除は新規作成時のみ行うことができます。

#### 配信対象者を各パターンに振り分ける



パターンを2つ以上に設定した場合も、各パターンに配信対象者を振り分けられます。
コントロールグループを含む各パターンの合計が100%になるように設定します。

**均等に振り分ける** をクリックすると、コントロールグループと各パターンを均等に振り分けます。
 
**均等に振り分ける(コントロールグループなし)** をクリックすると、コントロールグループを **0%** に設定し、 **100%** を各パターンで均等に振り分けます。
 

##### NOTE
- コントロールグループは **0%** ~ **99%** まで設定出来ます。
- 各パターンは **1%** ~ **100%** まで設定出来ます。
- 整数のみ設定出来ます。
- 振り分け設定は新規作成時のみ行うことが出来ます。
- 配信数の規模により、設定した割合と実際の配信数が乖離することがあります。



#### 効果測定（A/Bテスト）

##### 配信結果

プッシュ通知配信からしばらくすると、「配信結果」画面にプッシュ通知の開封率、コンバージョン率がパターンごとに表示されます。



| 項目 | 説明 |
| --- | --- |
| パターン | パターン名を表示します。 |
| オーディエンス | オーディエンス数を%で表示します。 |
| 配信数 | 配信数を表示します。 |
| 開封数 | 開封数を表示します。 |
| コンバージョン数 | コンバージョン数を表示します。 |
| コンバージョン率 | コンバージョン率を表示します。 |

##### NOTE
- コントロールグループの各データはキャンペーン自体の効果を判断しやすくするため、キャンペーン全体の **配信数**、**開封数**、**コンバージョン数**、**コンバージョン率** には反映されません。
- コントロールグループに属するユーザーに対してプッシュ通知は配信されないため、配信数は常に **-** で表示されます。
- コントロールグループの開封数は、コントロールグループに属するユーザーの中で、プッシュ通知配信時刻から1時間以内のアプリを起動したユーザー数を表示します。
- コントロールグループのコンバージョン数は、プッシュ通知の配信から1時間以内にアプリを起動し、アプリ起動から1時間以内にキャンペーンに設定したゴールのイベントを発生させた数を表示します。
- 開封率、コンバージョン率はそれぞれ開封数、コンバージョン数を、コントロールグループに属するユーザー数で割って算出されます。

##### A/Bテスト有意差 測定結果

A/Bテストの実行中にはA/Bテストの実行結果が表示されます。ここではコントロールグループを含む各パターンを選択した指標 (CVR, 開封率) を用いて比較を行えます。



| 項目 | 説明 |
| --- | --- |
| パターン | コントロールグループを含む、A/Bテストで送信を行う各パターンが表示されます。 |
| 開封率 | 開封率を表示します。 |
| 90%信頼区間 | 各パターンをベースラインと比較した場合の 90% 信頼区間が表示されます。90% 信頼区間そのものの意味については [FAQ > 信頼区間とはなんですか？](https://docs.repro.io/ja/faq/general/significant-difference/5.md) をご参照ください。 |
| ベースラインを変更する | A/Bテストで各パターンを比較する際に基準となるパターンをベースラインとして選択します。ベースラインを変更することで、様々なパターン間の比較ができます。 |
| 対象となる指標を変更する | A/Bテストで各パターンをベースラインと比較する際に用いる指標を選択します。指標には割合を表す値 (CVR, 開封率) が選択できます。また、一覧に表示する指標については編集画面から変更できます。 |

##### 参考：90%信頼区間の代表的なパターン読み取り例

ここでは、90%信頼区間の代表的なパターンの読み取り方について示します。

**例１：有意差がある場合**



このような表示の場合、パターンとベースラインとの差が有意であることを意味します。
配信を開始してから十分な期間が経過している場合、勝ちパターンの決定へと進むことを推奨します。

**例２：まだ有意差がない場合**



このような表示の場合、パターンとベースラインとの差が有意ではないことを意味します。結果が出るまでもう少し待つか、配信を開始してから十分な期間が経過している場合、差がないものとして次のキャンペーンの開始を検討することを推奨します。

**例３：有意差があり、勝ちパターンが決定している場合**



このような表示の場合、パターンとベースラインとの差が有意であることを意味します。このような表示しかない場合、ベースラインとして設定しているパターンを勝ちパターンして決定することを推奨します。

##### NOTE
- A/Bテスト有意差 測定結果は勝ちパターンを選択すると下記のような表示になり、各パターンの比較結果が表示されないようになります



##### 結果の推移

A/Bテストの結果の推移がグラフで表示されます。
「プッシュ通知の開封率」「コンバージョン率」がパターンごとに表示されます。



##### プッシュ通知一覧画面アイコン

A/Bテストを実行しているキャンペーンが公開中または非公開の場合に、プッシュ通知一覧画面で各キャンペーンのA/Bテストの状態を確認できます。



アイコンの表示条件は次のとおりです。

| アイコン | 表示条件 |
| --- | --- |
|  | 有意差があり、ベースラインを上回る結果のパターンが1つ以上存在する場合 |
|  | 有意差があり、ベースラインを下回る結果のパターンのみが存在する場合 |
|  | 有意差がないパターンのみが存在する場合 |
|  | 全てのパターンで計算ができない場合 |
|  | 勝ちパターンを選択済みの場合 |
|  | A/Bテストを実行していて、ベースラインとなるパターンか対象となる指標が設定されていない場合 |
| ー | キャンペーンがA/Bテストを実行していない場合 |

##### NOTE
- 有意差があり、ベースラインを上回る結果と下回る結果のキャンペーンが両方ともに存在する場合には、ベースラインを上回る結果が1つでも存在する場合として表示がされます
- ご不明点がある場合 [FAQ](https://docs.repro.io/ja/faq/general/index.md) もあわせてご確認ください

#### 勝ちパターンを選ぶ

勝ちパターンを選ぶと、以降のプッシュ通知ではそのパターンがすべてのユーザーに配信されるようになります。

リテンションレートの向上を目的として作成したプッシュ通知であれば開封率の高いパターンを、KPIの向上目的としているならば、コンバージョン率の高いパターンを選択するとよいでしょう。



### 許諾率を確認する

プッシュ通知の一覧画面から、どれだけのユーザーがプッシュ通知を許可しているかを表す許諾率を見ることができます。プッシュ通知による施策の効果を高め、リテンション率やコンバージョン率を上げるためには、プッシュ通知を許諾しているユーザーを増やすことが重要です。



なお、プッシュ通知の許諾率は以下の定義にもとづいて計算されます。

**許諾率 = 直近30日間に使用されたデバイスのうちプッシュ通知を許諾しているデバイス数 / 直近30日間に使用された全デバイス数**

##### NOTE
1ユーザーに対し、プッシュ通知が配信可能なデバイストークンやRegistration IDのうち登録された日時が最新のものから1,000件のデバイスにのみプッシュ通知を配信します。
 
テスト用のユーザーなど、1ユーザーに対して大量のデバイストークンやRegistration IDが紐付いている場合、1,001件目以降のデバイスにはプッシュ通知が配信されなくなりますのでご注意ください。

---

## APNs証明書の設定 (iOS)

Reproからプッシュ通知を送信するにはp8形式の鍵もしくはp12形式の証明書が必要です。そのために以下の手順ではp8形式の鍵とp12形式の証明書を作成します。

### APP IDの作成

証明書を作成するために必要な「APP ID」を作成します。

すでにAPP IDを作成済みの場合は [証明書の作成](#create-certificate) へお進みください。

[iOS Developer Center](https://developer.apple.com) のメンバーセンターにログインし、 **Account** ページに移動して、 **Certificates, IDs & Profiles** をクリックします。



**Identifiers** をクリックします。



**＋** ボタンをクリックして、新規のIdentifierの登録画面を開きます。次の画面で **APP IDs** を選択して、**Continue** をクリックします。



下記の項目を入力して **Continue** をクリックします。


- **Description:**
  - APP IDの名前を入力します。管理者が判別しやすい任意の名前を入力してください。
- **Bundle ID:**
  - APP IDの種類を決めます。Explicitを選択し、Bundle IDを入力します。Bundle IDはプッシュ通知を送信したいアプリのBundle IDと同一のもの設定してください。
- **Capabilities:**
  - アプリで使用するサービスを設定します。Push Notificationsにチェックします。

入力内容を確認し、 **Register** するとAPP IDが作成されます。





### 証明書の作成

#### p8形式の鍵を利用する場合

##### p8形式の鍵を発行する

[iOS Developer Center](https://developer.apple.com) にて、 **Certificates, IDs & Profiles** ページに移動し、下記のKeysの項目を選択し、Keyを追加するボタンを押してください。



下記のような画面が表示されるので、Apple Push Notification service（APNs）をチェックし、Keyに適当な名前をつけ、Configureを押してください。



任意のEnvironmentとKey Restrictionを選択し、Saveを押してください。
Reproでは全てのEnvironment(Sandbox, Production, Sandbox & Production)を利用することができます。

また、Key Restriction には「Topic-specific keys」または「Team-scoped keys」を指定できます。
選択する Key Restriction によって作成可能な p8 形式の鍵の数や制限が異なります。

詳細は [Apple 公式ドキュメント](https://developer.apple.com/documentation/usernotifications/establishing-a-token-based-connection-to-apns) をご確認ください。



EnvironmentとKey Restrictionを選択し、Saveを押すと
元の画面に遷移するので、そこでContinueを押してください。



すると下記のような確認画面が表示されますので、問題がなければRegisterを押してp8形式の鍵を発行してください。



上記を実行すると、下記のような画面が表示され、p8形式の鍵をダウンロードすることが可能になります。

この際に、表示されるKEY IDは後で利用するので、書き留めておいてください。



##### p8形式の鍵をReproにアップロード



[Reproの管理画面](https://app.repro.io/) を開き、 **設定 > プッシュ通知設定** を開きます。 **ファイルを選択する** をクリックして、先ほど作成したp8形式の鍵を選択します。

**① KEY IDの入力**

上記で書き留めておいたKEY IDを入力してください。

**② Team IDの入力**

[iOS Developer Center](https://developer.apple.com) のメンバーセンターにログインし、 **Membership** のページに移動すると下記の画像のような画面が表示されますので、そちらから確認が可能です。



**③ Bundle ID**

アプリのBundle IDになりますので、Xcodeからご確認ください。

**④ 環境の設定**

ご利用中のSDKトークンに紐づくアプリのビルド設定に応じて、環境を選択してください。

##### NOTE
- 上記の環境の設定では、本番環境では必ずProductionを、開発環境の場合はSandboxを選択してください。
- 本番環境と開発環境の定義は以下の通りです
  : - 本番環境: App Storeからダウンロードしたアプリもしくは、TestFlightなどのテストアプリ配布ツール等を利用してAdHoc配布されたアプリの場合
    - 開発環境: IDE(統合開発環境)から直接ビルドしたアプリケーションの場合

#### p12形式の証明書を利用する場合

##### CSRの作成

証明書を作成するために必要な「CSR（証明書署名要求）」を作成します。CSRはお使いのMacのキーチェーンアクセスで作成することができます。

キーチェーンアクセス -> 証明書アシスタント -> 認証局に証明書を要求...を選択します。



**メールアドレス** と **通称** を入力し、 **ディスクに保存** にチェックして **続ける** をクリックします。



CSRファイルが作成されますので、任意の場所に保存します。



##### CSRのアップロード

[iOS Developer Center](https://developer.apple.com) にて、 **Certificates, IDs & Profiles** ページに移動します。

作成した App IDの行をクリックします。



Push Notificationsの欄の **Configure** をクリックします。



クリックすると、証明書作成のポップアップが表示されます。



APNsには、DevelopmentとProductionがあり、それぞれ異なる証明書が必要です。
DevelopmentとProductionは、アプリのビルド方法によって、どちらを使用するか変わります。
詳しくは、下記の注釈をご参照ください。

今回はDevelopmentの証明書を作ります。

##### NOTE
プッシュ通知証明書は、配信対象となるアプリの配布方法(Ad hocまたはIn-House）によって証明書の種類を分けて登録する必要があります。下記の様にそれぞれのアプリ環境にあわせて正しい種類の証明書を選択して下さい。

- Development SSL Certificate: IDE(統合開発環境)から直接ビルドしたアプリケーションの場合
- Production SSL Certificate: App Storeからダウンロードしたアプリもしくは、TestFlightなどのテストアプリ配布ツール等を利用してAdHoc配布されたアプリの場合

証明書を作成するためにはCSRが必要という旨の説明とアップロード用のフォームが表示されます。

**Choose File** にて先ほど作成したCSRファイルを選択し、 **Continue** をクリックします。



証明書が作成されますので **Download** をクリックして証明書をダウンロードしてください。



##### 証明書をp12形式に変換する

先ほどダウンロードした証明書(.cer形式のファイル)をダブルクリックするとキーチェーンアクセスが起動します。証明書は **Apple [Development/Production] iOS Push Services: [Bundle ID]** もしくは **Apple Push Services: [Bundle ID]** のような名前でキーチェーンアクセスに追加されていますので、検索窓にBundle IDの一部を入力すると候補を絞ることができます。



証明書の左の三角マークをクリックし、 **証明書** と **秘密鍵** が表示させます。 **証明書** のみを選択した状態で **control** キーを押しながらクリックします。



表示されたポップアップにて **[証明書名]を書き出す…** を選択します。



表示されたダイアログにてフォーマットが **個人情報交換（.p12）** 形式であることを確認し、任意の場所に保存します。



**書き出した項目を保護するために使用されるパスワードを入力** というダイアログが表示されます。ここで入力したパスワードは、次節、[p12形式の証明書をReproにアップロード](#update-p12-repro-dashboard) の手順の際に必要ですので、覚えておいてください。パスワードを設定しなくても問題ありません。



キーチェーンアクセスが証明書を書き出すためにMacのパスワードを入力するとp12形式の証明書が保存されます。





##### p12形式の証明書をReproにアップロード

[Reproの管理画面](https://app.repro.io/) を開き、 **設定 > プッシュ通知設定** を開きます。 **P12ファイルを選択** をクリックして、先ほど作成したp12ファイルを選択します。p12ファイル作成時にパスワードを設定した場合は「証明書のパスワード」欄にパスワードを入力してください。



##### NOTE
- p8形式の鍵とp12形式の証明書を両方とも管理画面からアップロードした場合には、p8の鍵が使用されます。しかしながら、AppleDeveloper側でp8形式の鍵がRevokeされるとp12形式の証明書が利用されることがあります。

### Provisioning Profileの設定

iOS Dev Centerの **Certificates, IDs & Profiles** にてProfilesを開き、Provisioning Profileを追加するために **＋** ボタンをクリックします。



Provisioning Profileの種類を「iOS App Development」「Ad Hoc」「App Store」のいずれかから選択して **Continue** をクリックします。



プッシュ通知を送信するAPP IDを選択して **Continue** をクリックします。



Provisioning Profileに含める証明書を選択して **Continue** をクリックします。



インストール対象の端末を選択して **Continue** をクリックします（DevelopmentおよびAd HocのProvisioning Profile作成時のみ）。



Provisioning Profileの名前を入力して **Generate** をクリックするとProvisioning Profileが作成されます。



「Download」をクリックして作成されたProvisioning Profileをダウンロードします。



ダウンロードしたProvisioning Profileをダブルクリックして、Xcodeに取り込みます。

正常に取り込みが完了した場合、XcodeはそのプロジェクトにあったProvisioning Profileを自動的に選択します。



自動的に選択されたProvisioning Profileが作成したProvisioning Profileと違う場合、手動で設定することも可能です。

Xcodeの **Singing & Capabilities** にて作成したProvisioning Profileを設定します。

**Automatic manage signing** のチェックを外し、 **Provisioning Profile** のドロップダウンメニューから、作成したProvisioning Profileを選択してください。

---

objc,swift



## プッシュ通知（iOS）

### プッシュ通知の設定

[APNs証明書の設定 (iOS)](https://docs.repro.io/ja/dev/sdk/push-notification/setup-ios.md) を参照し、設定してください。



### バッジを消す処理の実装

プッシュ通知作成フォームから [「バッジを表示する」をオン](https://docs.repro.io/ja/dashboard/campaign/push-notification.md#clear-badge-setting) にして送信すると、プッシュ通知を受信したアプリのアイコンにバッジが自動で表示されます。

表示されたバッジを消す方法はiOSのバージョンによって異なり、以下どちらかを 0 にセットする必要があります。

- `UNUserNotificationCenter` クラスの [setBadgeCount](https://developer.apple.com/documentation/usernotifications/unusernotificationcenter/setbadgecount(_:withcompletionhandler:))
- `UIApplication` クラスの [applicationIconBadgeNumber](https://developer.apple.com/documentation/uikit/uiapplication/1622918-applicationiconbadgenumber)

アプリの仕様に合わせて任意のタイミングで `setBadgeCount` あるいは `applicationIconBadgeNumber` に 0 をセットしてください。

例えば、アプリがActiveになったタイミングでバッジを消す場合は `UIApplicationDelegate` の [applicationDidBecomeActive:](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622956-applicationdidbecomeactive) で次の処理を実行します。

```objc
// AppDelegate.m

@implementation AppDelegate
- (void)applicationDidBecomeActive:(UIApplication *)application
    ...
    if (@available(iOS 16.0, *)) {
        UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
        [center setBadgeCount:0];
    } else {
        application.applicationIconBadgeNumber = 0;
    }
    ...
```

```swift
// AppDelegate.swift

class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

    func applicationDidBecomeActive(_ application: UIApplication) {
        ...
        if #available(iOS 16.0, *) {
            let center = UNUserNotificationCenter.current()
            center.setBadgeCount(0)
        } else {
            application.applicationIconBadgeNumber = 0
        }
        ...
```

##### NOTE
[「バッジを表示する」をオン](https://docs.repro.io/ja/dashboard/campaign/push-notification.md#clear-badge-setting) にしたプッシュ通知を送信する場合は、必ずバッジクリア処理を実装してください。

##### NOTE
アプリアイコンにバッジが表示されている場合にバッジクリア処理を実行することで処理によって挙動が変わります。バッジが表示されていない場合はバッジクリア処理を実行しても何も起きません。

- `setBadgeCount` : 0 をセットすることでバッジが消え、通知センターに残っている通知は消えません
- `applicationIconBadgeNumber` : 0 をセットすることでバッジが消え、通知センターに残っている通知も消えます



### デバイストークンをReproに送信

プッシュ通知の宛先を指定するためにデバイストークンをReproに送信します。

XcodeのCapabilitiesにてPush NotificationsをONにします。



次に下記のコードを追加してください。

```objc
// AppDelegate.m

#import <Repro/Repro.h>
#import <UserNotifications/UserNotifications.h>
    ...
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    ...
    if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_9_x_Max) {
        UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
        center.delegate = self;
        [center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionBadge | UNAuthorizationOptionSound) completionHandler:^(BOOL granted, NSError * _Nullable error) {
        }];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    } else {
        UIUserNotificationType types = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    }
    return YES;
}
```

```swift
// AppDelegate.swift

import Repro
import UserNotifications
    ...
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
        ...
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        ...
        if #available (iOS 10.0, *) {
            let center = UNUserNotificationCenter.current()
            center.delegate = self
            center.requestAuthorization(options: [.sound, .alert, .badge], completionHandler: { (granted, error) in
            })
            application.registerForRemoteNotifications()
        } else {
            let settings: UIUserNotificationSettings = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
            UIApplication.shared.registerUserNotificationSettings(settings)
            UIApplication.shared.registerForRemoteNotifications()
        }
        return true
    }
```

```objc
// AppDelegate.m
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
    [Repro setPushDeviceToken:deviceToken];
}

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
    NSLog(@"Remote Notification Error: %@", error);
}
```

```swift
// AppDelegate.swift
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    Repro.setPushDeviceToken(data: deviceToken)
}

func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
    print("Remote Notification Error: \(error)")
}
```

デバイストークンの取得に成功した場合は `application:didRegisterForRemoteNotificationsWithDeviceToken:` メソッドが呼び出されるので、その中でReproにデバイストークンを渡します。

デバイストークンの取得に失敗した場合は `application:didFailToRegisterForRemoteNotificationsWithError:` メソッドが呼び出されるので、エラーの内容を見て適宜対処します。

以上の実装をした後にアプリを起動すると、下記のようなプッシュ通知の許諾ダイアログが表示されます。



このダイアログにて **OK** を選択すると `application:didRegisterForRemoteNotificationsWithDeviceToken:` メソッドが呼び出され、Reproにデバイストークンが設定されます。

以上でプッシュ通知の受信準備は完了です。



### オプション：リッチ通知の受信準備

iOS 10から画像や動画、音声ファイルなどを通知に利用することができるリッチ通知機能が追加されました。リッチ通知を受信するためには下記の手順が必要です。

#### Notification Service Extensionの作成

Xcodeのメニューの **File -> New -> Target...** をクリックします。



**iOS -> Notification Service Extension -> Next** をクリックします。



任意のProduct Nameを入力してFinishをクリックします。



下記のようなダイアログが出てきたら `Activate` をクリックします。



#### Notification Service Extensionの実装

`Notification Service Extension` に下記の記述をします。

```objc
#import <UserNotifications/UserNotifications.h>

...

@implementation NotificationService

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {

    self.contentHandler = contentHandler;
    self.bestAttemptContent = [request.content mutableCopy];

    NSDictionary *attachment = request.content.userInfo[@"rpr_attachment"];
    if (!attachment) {
        contentHandler(self.bestAttemptContent);
        return;
    }

    NSString *urlStr = attachment[@"url"];
    NSString *type = attachment[@"type"];
    NSURL *url = [NSURL URLWithString:urlStr];

    [[[NSURLSession sharedSession] downloadTaskWithURL:url
                                     completionHandler:^(NSURL * _Nullable location,
                                                         NSURLResponse * _Nullable response,
                                                         NSError * _Nullable error) {

                                         if (error) {
                                             contentHandler(self.bestAttemptContent);
                                             return;
                                         }

                                         NSString *fileName = [NSString stringWithFormat:@"%@.%@", [[NSUUID UUID]UUIDString], type];
                                         NSURL *fileURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:fileName]];
                                         [[NSFileManager defaultManager] moveItemAtURL:location toURL:fileURL error:nil];

                                         NSError *attachError = nil;
                                         UNNotificationAttachment *attachment = [UNNotificationAttachment attachmentWithIdentifier:@"IDENTIFIER" URL:fileURL options:nil error:&attachError];
                                         if (!attachError) {
                                             self.bestAttemptContent.attachments = @[attachment];
                                         }

                                         contentHandler(self.bestAttemptContent);
                                     }] resume];
}
```

```swift
import UserNotifications
...
class NotificationService: UNNotificationServiceExtension {

    var contentHandler: ((UNNotificationContent) -> Void)?
    var bestAttemptContent: UNMutableNotificationContent?

    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        self.contentHandler = contentHandler
        bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)

        if let attachment = request.content.userInfo["rpr_attachment"] as? [String: String] {
            if let urlString = attachment["url"], let fileURL = URL(string: urlString), let type = attachment["type"] {

                URLSession.shared.downloadTask(with: fileURL) { (location, response, error) in
                    if let location = location {
                        let fileName = UUID().uuidString + "." + type
                        let tmpFile = "file://".appending(NSTemporaryDirectory()).appending(fileName)
                        let tmpUrl = URL(string: tmpFile)!
                        try? FileManager.default.moveItem(at: location, to: tmpUrl)

                        if let attachment = try? UNNotificationAttachment(identifier: "IDENTIFIER", url: tmpUrl, options: nil) {
                            self.bestAttemptContent?.attachments = [attachment]
                        }
                    }
                    contentHandler(self.bestAttemptContent!)
                }.resume()
            }
        } else {
            contentHandler(self.bestAttemptContent!)
        }
    }
```

上記の実装が終わったら、 [プッシュ通知作成画面](https://docs.repro.io/ja/dashboard/campaign/push-notification.md#push-create-message) をご覧ください。



### オプション：ユニバーサルリンクを使用する



端末に表示されたプッシュ通知およびアプリ内メッセージに設定されたリンクをタップした際に実行されるURLには、ユニバーサルリンク（またはアプリリンクと呼ばれる）を指定することが可能です。
（簡単のため、以下ではこれらをユニバーサルリンクと呼びます）

アプリにてユニバーサルリンクの実行時の処理を追加するには、以下の通り実装を行う必要があります。
（ここで設定された動作は、プッシュ通知およびアプリ内メッセージ対し有効となります。）

#### ユニバーサルリンクのURLパターンを登録する

ユニバーサルリンクを利用するためには、まずユニバーサルリンクのURLのパターン（正規表現）を指定する必要があります。

##### NOTE
パターン（正規表現）に合致すると、プッシュ通知の開封時や、アプリ内メッセージの遷移先に設定されたURLに対して、後述のコールバック処理をキックします。

また、アプリ内メッセージでHTMLコンテンツを表示するとき、そのコンテンツ内で発生したリクエストに対してもユニバーサルリンクの判定が行われます。

この指定は、iOSの場合は `AppDelegate` または `.plist` ファイル、Androidの場合は `Application` 継承クラス または `AndroidManifest.xml` ファイルのどちらか一方に記述することで行うことができます。

```objc
// AppDelegate.m

#import <Repro/Repro.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [Repro addOpenUrlFilterRegEx:@"https://example\\.com/page/"];
    [Repro addOpenUrlFilterRegEx:@"your-domain\\.com/.+\?universal=true"];
    ...
}


// .plist file
/*
<dict>
    <key>RPROpenUrlFilterRegExList</key>
    <array>
        <string>https://example\.com/page/</string>
        <string>your-domain\.com/.+\?universal=true</string>
    </array>
    ...
</dict>
*/
```

```java
// MyApplication.java

import io.repro.android.Repro;

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        Repro.addOpenUrlFilterRegEx("https://example\\.com/page/");
        Repro.addOpenUrlFilterRegEx("your-domain\\.com/.+\\?universal=true");
        ...
    }
...
}


// AndroidManifest.xml
// To specify multiple URL patterns, enter them separated by commas.
<application>
    ...
    <meta-data
        android:name="io.repro.android.OpenUrlFilterRegExList"
        android:value="https://example\\.com/page/;your-domain\\.com/.+\\?universal=true">
    </meta-data>
</application>
```

```kotlin
// MyApplication.kt

import io.repro.android.Repro

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        Repro.addOpenUrlFilterRegEx("https://example\\.com/page/")
        Repro.addOpenUrlFilterRegEx("your-domain\\.com/.+\\?universal=true")
        ...
    }
    ...
}


// AndroidManifest.xml
// To specify multiple URL patterns, enter them separated by commas.
<application>
    ...
    <meta-data
        android:name="io.repro.android.OpenUrlFilterRegExList"
        android:value="https://example\\.com/page/;your-domain\\.com/.+\\?universal=true">
    </meta-data>
</application>
```

```swift
// AppDelegate.swift

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
{
    Repro.add(openUrlFilterRegEx: "https://example\\.com/page/")
    Repro.add(openUrlFilterRegEx: "your-domain\\.com/.+\\?universal=true")
    ...
}

// .plist file
/*
<dict>
    <key>RPROpenUrlFilterRegExList</key>
    <array>
        <string>https://example\.com/page/</string>
        <string>your-domain\.com/.+\?universal=true</string>
    </array>
    ...
</dict>
*/
```

```dart
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

```csharp
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

```cpp
// YourAppNameScene.cpp

bool YourAppName::init() {
    ReproCpp::addOpenUrlFilterRegEx("https://example\\.com/page/");
    ReproCpp::addOpenUrlFilterRegEx("your-domain\\.com/.+\\?universal=true");
    ...
}
```

```js-cordova
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

```js-react-native
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

##### WARNING
ユニバーサルリンクとして設定するURLパターンは、可能な限り **ドメインとパスまで含めて具体的に指定** し、 **全て小文字で指定** してください。

もし、 https のようにスキームのみを指定した場合、アプリ内メッセージで表示された画面内で実行されたスクリプトなどによるリクエストもユニバーサルリンクと誤って判定され、意図しないタイミングでコールバック処理が実行される可能性があります。

また、URLパターンのスキーム/ドメイン部分に大文字を使用した場合、HTMLアプリ内メッセージで表示したボタンからユニバーサルリンクを使って遷移させようとするときに、スキーム/ドメイン部分が自動的に小文字に変換されて処理されます。パターン（正規表現）に一致せず、意図したタイミングでコールバック処理が実行されない可能性があります。

#### ユニバーサルリンク実行時の処理を登録する

次に、ユニバーサルリンクが実行された際に動作するコールバック処理を実装します。
処理内には、例えばURLのパターンに応じて画面遷移を行う動作などを記述します。

```objc
#import <Repro/Repro.h>

...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [Repro setOpenUrlCallback:^(NSURL *url) {
        if ([url.host isEqualToString:@"example.com"]) {
            // In case of your universal link perform navigation, present content, ...
            handleUniversalLink(url);
        }
    }];

    ...
    [Repro setup:@"YOUR_APP_TOKEN"];
    ...
}
```

```swift
// Set a callback that is executed everytime an URL is about to be opened
Repro.setOpenUrlCallback { url in
    if url.host == "example.com" {
        // In case of your universal link perform navigation, present content, ...
        handleUniversalLink(url)
    }
}
...
Repro.setup(token: "YOUR_APP_TOKEN")
...
```

```java
import io.repro.android.Repro;

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        // In order to execute a callback when a push notification is tapped,
        // the callback must be set in Application, not Activity.
        Repro.setOpenUrlCallback(new Repro.OpenUrlCallback() {
            // ** This callback method is executed in the main thread **
            @Override
            public void onOpened(Uri uri) {
                if ("example.com".equals(uri.getHost())) {
                    // In case of your universal link perform navigation, present content, ...
                }
            }
        });

        ...
        Repro.setup(this, YOUR_APP_TOKEN);
        ...
    }
    ...
}
```

```kotlin
import io.repro.android.Repro

class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        // In order to execute a callback when a push notification is tapped,
        // the callback must be set in Application, not Activity.
        Repro.setOpenUrlCallback { uri ->
            // ** This callback method is executed in the main thread **
            if (uri.host == "example.com") {
                // In case of your universal link perform navigation, present content, ...
            }
        }

        ...
        Repro.setup(this, "YOUR_APP_TOKEN")
        ...
    }
    ...
}
```

```dart
Repro.setOpenUrlCallback((uri) { // uri is of type Uri
   debugPrint("Universal Link Callback Handler received: " + uri.toString());
});
```

```csharp
// Somewhere before Repro.Setup(...)
Repro.SetOpenUrlCallback(uri => // uri is of type Uri
{
    Debug.Log("Universal Link Callback Handler received: " + uri.ToString());
});
```

```cpp
bool YourAppName::init() {
    ReproCpp::addOpenUrlFilterRegEx(...);

    ReproCpp::setOpenUrlCallback([](const char *url) {
        if (strcmp(url, "example.com") == 0) {
            // In case of your universal link perform navigation, present content, ...
        }
    });

    ReproCpp::setup("YOUR_APP_TOKEN")
    ...
}
```

```js-cordova
Repro.setOpenUrlCallback(function(url) { // url is of type String
    alert('Universal Link Callback Handler received: ' + url);
    if (url.includes("http://example.org")) {
        // In case of your universal link perform navigation, present content, ...
    }
});
```

```js-react-native
Repro.setOpenUrlCallback( (url) => {  // url is of type String
    console.log('Universal Link Callback Handler received: ' + url);
    if (url.includes("http://example.org")) {
        // In case of your universal link perform navigation, present content, ...
    }
});
```

---

## FCMの設定 (Android)

Reproからプッシュ通知を送るには、Firebase Cloud Messagingを利用するための `google-services.json` ファイル及び秘密鍵を以下の手順で生成し、Reproに登録する必要があります。

### プロジェクトの作成

[Firebase Console](https://console.firebase.google.com/?hl=ja) を開き、プロジェクトを新規作成します。



各項目を設定し、 **プロジェクトを作成** をクリックしてください。





### アプリの登録

#### 新規にアプリを登録する場合

作成されたプロジェクトに Android アプリを登録し、 `google-services.json` を生成します。

**プロジェクトの設定** を選択してください。



ページの下にある **Androidアイコン** をクリックしてください。



各項目を設定し、**アプリを登録** をクリックしてください。



**google-services.json をダウンロード** をクリックしてください。ダウンロードされた `google-services.json` は後から使用しますので、手元に保管しておいてください。



#### すでにアプリを登録済みの場合

**プロジェクト設定 > 全般** を選択し、 `google-services.json` をダウンロードしてください。





### Firebase Cloud Messaging API（V1）を有効にする

**プロジェクト設定 > Cloud Messaging** を選択し、Firebase Cloud Messaging API (V1) の **Google Cloud Console で API を管理** をクリックします。



**Firebase Cloud Messaging API** を有効にします。



**プロジェクト設定 > Cloud Messaging** の画面をリロードし、Firebase Cloud Messaging API (V1) が有効になっていることを確認します。



### Firebaseの秘密鍵を生成

**プロジェクト設定 > サービスアカウント** を選択し、**新しい秘密鍵を生成** をクリックし、表示されるモーダルの **キーを生成** をクリックして秘密鍵をダウンロードしてください。





### Firebaseの秘密鍵をReproに登録

**設定 > プッシュ通知設定** を開き、以下の手順を実行してください。

- **秘密鍵を選択する** をクリックしてさきほどダウンロードしたFirebaseの秘密鍵を選択してください
- **保存** をクリックしてください

---

java, kotlin, dart



## プッシュ通知（Android）

### プッシュ通知の設定

[FCMの設定 (Android)](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md) を参照し、設定してください。

### Firebase SDKを導入する

[FCMの設定 (Android)](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md) でダウンロードした `google-services.json` をアプリモジュールのディレクトリにコピーし、プロジェクトのbuild.gradleに以下を追加してください。

```groovy
buildscript {
    ...
    dependencies {
        ...
        classpath 'com.google.gms:google-services:4.3.4'
    }
}

allprojects {
    ...
    repositories {
        ...
        google()
    }
}
```

アプリのbuild.gradleに以下を追加してください。

```groovy
dependencies {
    implementation 'com.google.firebase:firebase-messaging:20.3.0'
}

apply plugin: 'com.google.gms.google-services'

// This part does not need to be implemented in a Flutter app.
```

##### WARNING
firebase-messagingのバージョン17.1.0以上を指定してください。17.1.0未満は、Repro SDKでRegistration IDを取得できません。

##### NOTE
Gradle 3.4 未満のバージョンの場合は 'implementation' が利用できません。
'compile'を利用してください。



### `AndroidManifest.xml` ファイルを編集する

#### Receiverの登録

以下のXML中の "YOUR_PACKAGE_NAME" をアプリケーションのパッケージ名に置き換え、AndroidManifest.xmlの `<application>` タグの中に追加してください。

```xml
<receiver
    android:name="io.repro.android.ReproReceiver"
    android:exported="true"
    android:permission="com.google.android.c2dm.permission.SEND">
    <intent-filter>
        <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        <category android:name="YOUR_PACKAGE_NAME" />
    </intent-filter>
</receiver>
```



#### 通知チャンネルの設定

Android Oにて、ユーザーが通知を管理できるように通知チャンネルが導入されました。

Repro SDKで利用する通知チャンネルの設定を行うには、「ID」「名前」「ユーザー向けの説明」「badgeの表示有無」を指定する必要があります。
以下のXML中の `value`, `resource` を設定したい値に書き換え、AndroidManifest.xmlの `<application>` タグの中に追加してください。
IDと名前の指定は必須、その他は省略可能です。「ユーザー向けの説明」省略時は空文字列、「badgeの表示有無」省略時はbadgeの表示有りとなります。

##### WARNING
- アプリのtargetSDKVersionが26以上かつAndroid O以降の機種で動作させる場合、IDと名前が指定されていなければSDKはReproからのプッシュ通知を表示いたしませんのでご注意ください。
- `ChannelId` に指定する値は、整数や小数ではなく `test ID` のような文字列を指定してください。文字列以外の値を指定するとチャンネルIDの指定がうまく動作せず、プッシュ通知が表示されません。
- `ChannelName` と `ChannelDescription` の設定は `android:resource` 属性を使用してください。

```xml
<meta-data
    android:name="io.repro.android.PushNotification.ChannelId"
    android:value="YOUR_CHANNEL_ID">
</meta-data>

<meta-data
    android:name="io.repro.android.PushNotification.ChannelName"
    android:resource="@string/YOUR_CHANNEL_NAME">
</meta-data>

<meta-data
    android:name="io.repro.android.PushNotification.ChannelDescription"
    android:resource="@string/YOUR_CHANNEL_DESCRIPTION">
</meta-data>

<meta-data
    android:name="io.repro.android.PushNotification.ShowBadge"
    android:value="true">
</meta-data>
```

指定されたIDの通知チャンネルが存在しない場合はAndroidManifest.xmlの指定を基にSDKが自動で作成し、指定されたIDの通知チャンネルが存在する場合は既存のものを利用します。

既存のものを利用する場合、SDKは「名前」、「ユーザー向けの説明」及び「チャンネルの重要度」を更新します。

また、アプリのtargetSDKVersionが25以下の場合、あるいは、Android O未満の機種の場合は、SDKは上記の通知チャンネルに関する設定を無視します。

##### NOTE
通知チャンネルはAndroid Oで導入されたAndroidの標準機能です。通知チャンネルの詳細は [こちら](https://developer.android.com/preview/features/notification-channels.html?hl=ja) をご覧ください。



#### アイコンと背景色のカスタマイズ

Android5.0以降の機種で、通知エリアに表示されるアイコンとその背景色をカスタマイズする場合は、以下のXMLをAndroidManifest.xmlの `<application>` タグの中に追加してください。Android5.0未満の機種では以下の設定は無視され、通知エリアにはアプリケーションのアイコンおよびシステムデフォルトの背景色が使用されます。

```xml
<meta-data
    android:name="io.repro.android.PushNotification.SmallIcon"
    android:resource="@drawable/YOUR_ICON_ID">
</meta-data>

<meta-data
    android:name="io.repro.android.PushNotification.AccentColor"
    android:resource="@color/YOUR_COLOR_ID">
</meta-data>
```

### Registration IDをReproに送信

##### WARNING
targetSdk 33（Android 13）以上では、通知許諾がオプトイン形式になりました。
 
通知許諾ダイアログの実装が必要です。
 
 
- `AndroidManifest.xml` に [通知権限（POST_NOTIFICATIONS）](https://developer.android.com/about/versions/13/changes/notification-permission#use) を追加する
- 通知権限を求める [ダイアログ](https://firebase.google.com/docs/cloud-messaging/android/client#request-permission13) を実装する

これらが完了していない場合、 アプリの実装が必要です。
 
[ダイアログを表示するタイミング](https://developer.android.com/about/versions/13/changes/notification-permission#wait-to-show-prompt) は任意で調整することができます。
 

Reproの `setup()` を呼び出した直後に、 `Repro.enablePushNotification` を呼び出してください。

```java
 import io.repro.android.Repro;

 public class MyApplication extends Application {

     @Override
     public void onCreate() {
         super.onCreate();

         ...

         Repro.setup(this, "YOUR_APP_TOKEN");
         Repro.enablePushNotification();

         ...
     }
 }
```

```kotlin
 import io.repro.android.Repro

 class MyApplication : Application() {

     override fun onCreate() {
         super.onCreate()

         ...

         Repro.setup(this, "YOUR_APP_TOKEN")
         Repro.enablePushNotification()

         ...
     }
 }
```

```dart
// This section should be implemented in Java, even for Flutter applications.
```

`FirebaseMessagingService` を継承したクラスの `onNewToken` にて `Repro.setPushRegistrationID` を呼び出してください。

```java
 import io.repro.android.Repro;

 public class MyFirebaseMessagingService extends FirebaseMessagingService {
     ...
     @Override
     public void onNewToken(String token) {
         Repro.setPushRegistrationID(token);
     }
     ...
 }
```

```kotlin
 import io.repro.android.Repro

 class MyFirebaseMessagingService : FirebaseMessagingService() {
     ...
     override fun onNewToken(token: String) {
         Repro.setPushRegistrationID(token)
     }
     ...
 }
```

```dart
// main.dart
FirebaseMessaging messaging = FirebaseMessaging.instance;
messaging.onTokenRefresh.listen((token) async {
    await Repro.setPushRegistrationID(token);
});
```

以下をAndroidManifest.xmlの `<application>` タグの中に追加してください。

```java
<service
    android:name=".MyFirebaseMessagingService">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>
```

```kotlin
<service
    android:name=".MyFirebaseMessagingService">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>
```

```dart
// This part does not need to be implemented in a Flutter app.
```

##### NOTE
AndroidManifest.xmlに複数のFirebaseMessagingServiceを追加しても、その内の一つのFirebaseMessagingServiceしか動作しません。

このため、既にFirebaseMessagingServiceを継承したクラスを実装している場合は、そのクラスの `onNewToken` にて `Repro.setPushRegistrationID` を呼び出すようにし、新たにFirebaseMessagingServiceを継承したクラスを作成しないでください。

##### WARNING
ReproからAndroid端末へ配信したプッシュ通知は通知ドロワーに登録されます。ヘッドアップ通知として取り扱われません。

もしヘッドアップ通知を実現したい場合は [Reproからプッシュ通知を受信した際、デフォルトでバナー表示されますか？](https://docs.repro.io/ja/faq/app/push/2.md) をご参照ください。

上記の実装が終わったら、 [プッシュ通知作成画面](https://docs.repro.io/ja/dashboard/campaign/push-notification.md#push-create-message) をご覧ください。



### オプション：プッシュ通知受信時の動作をカスタマイズする

プッシュ通知受信時の動作をカスタマイズしたい場合は、FirebaseMessagingServiceのonMessageReceivedメソッドを実装してください。

#### FirebaseMessagingServiceのonMessageReceivedを実装する

`onMessageReceived` をオーバーライドして、以下の3つのメソッドを呼び出してください。

* `Repro.applicationShouldHandlePushNotification` を呼び出して、受信したメッセージをアプリケーションで処理すべきか判定してください。このメソッドが `false` を返す場合、そのメッセージはSDKで処理されます。
* `Repro.isAlreadyReceivedPushNotification` を呼び出して、受信済みのメッセージか判定してください。アプリケーションのアンインストール・再インストールを繰り返した場合、重複したメッセージが届く場合があります。
* `Repro.markPushNotificationReceived` を呼び出して、受信済みのメッセージであることを記録してください。

##### NOTE
スタンダード形式の通知を受信するためには `ReproReceiver` が必要です。AndroidManifest.xmlに登録されている `ReproReceiver` を削除しないでください。

```java
@Override
public void onMessageReceived(RemoteMessage message) {
    Map<String, String> data = message.getData();

    // check whether the application should handle this push notification.
    if (!Repro.applicationShouldHandlePushNotification(this, data)) {
        Log.d(TAG, "Ignore push notification: it will be handled by SDK: " + data.toString());
        return;
    }

    // check whether this push notification is already received.
    if (Repro.isAlreadyReceivedPushNotification(this, data)) {
        Log.d(TAG, "Ignore push notification: it is already received: " + data.toString());
        return;
    }

    // mark this push notification as "received".
    Log.d(TAG, "Mark push notification as received: " + data.toString());
    Repro.markPushNotificationReceived(this, data);

    // Implement procedures unique to the application here
    ...
}
```

```kotlin
override fun onMessageReceived(message: RemoteMessage) {
    val data: Map<String, String> = message.data

    // check whether the application should handle this push notification.
    if (!Repro.applicationShouldHandlePushNotification(this, data)) {
        Log.d(TAG, "Ignore push notification: it will be handled by SDK: $data")
        return
    }

    // check whether this push notification is already received.
    if (Repro.isAlreadyReceivedPushNotification(this, data)) {
        Log.d(TAG, "Ignore push notification: it is already received: $data")
        return
    }

    // mark this push notification as "received".
    Log.d(TAG, "Mark push notification as received: $data")
    Repro.markPushNotificationReceived(this, data)

    // Implement procedures unique to the application here
    ...
}
```

```dart
// main.dart
FirebaseMessaging.onMessage.listen((RemoteMessage message) async {

    // check whether the application should handle this push notification.
    final shouldHandle = await Repro.applicationShouldHandlePushNotification(message.data);
    if (!shouldHandle) {
        debugPrint("Ignore push notification: it will be handled by SDK: ${message.data.toString()}");
        return;
    }

    // check whether this push notification is already received.
    final isReceived = await Repro.isAlreadyReceivedPushNotification(message.data);
    if (isReceived) {
        debugPrint("Ignore push notification: it is already received: ${message.data.toString()}");
        return;
    }

    // mark this push notification as "received".
    debugPrint("Mark push notification as received: ${message.data.toString()}");
    await Repro.markPushNotificationReceived(message.data);

    // Implement procedures unique to the application here
    ...
});
```

#### 開封された通知をトラッキングする

スタンダード形式のメッセージの場合はSDKが自動で開封をトラッキングします。JSON形式のメッセージの場合は、アプリケーションから `Repro.trackNotificationOpened` を呼び出してトラッキングする必要があります。

以下では、JSON形式のメッセージからActivityを起動する通知を作成し、起動されたActivity側で `Repro.trackNotificationOpened` を呼び出すサンプルを示します。

```java
public class MyFirebaseMessagingService extends FirebaseMessagingService {
    private static final String TAG = "MessagingService";
    private static final String CHANNEL_ID = "custom-firebase-messaging-service-channel";

    private final Random mRandom = new Random();

    @Override
    public void onNewToken(String token) {
        Repro.setPushRegistrationID(token);
    }

    @Override
    public void onMessageReceived(RemoteMessage message) {
        final int identifier = mRandom.nextInt();
        Map<String, String> data = message.getData();

        // check whether the application should handle this push notification.
        if (!Repro.applicationShouldHandlePushNotification(this, data)) {
            Log.d(TAG, "Ignore push notification: it will be handled by SDK: " + data.toString());
            return;
        }

        // check whether this push notification is already received.
        if (Repro.isAlreadyReceivedPushNotification(this, data)) {
            Log.d(TAG, "Ignore push notification: it is already received: " + data.toString());
            return;
        }

        // mark this push notification as "received".
        Log.d(TAG, "Mark push notification as received: " + data.toString());
        Repro.markPushNotificationReceived(this, data);

        String messageText;
        if (data.containsKey("message")) {
            messageText = data.get("message");
        } else {
            messageText = "default message";
        }

        final Notification.Builder builder = new Notification.Builder(this)
                .setContentTitle(this.getResources().getString(R.string.app_name))
                .setContentText(messageText)
                .setSmallIcon(R.mipmap.ic_launcher_round)
                .setAutoCancel(true);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            createOrUpdateChannel();
            builder.setChannelId(CHANNEL_ID);
        }

        Intent resultIntent = new Intent(this, SomeActivity.class);

        String notificationIdKey = data.get(io.repro.android.ReproReceiver.NOTIFICATION_ID_KEY);
        if (notificationIdKey != null) {
            resultIntent.putExtra(io.repro.android.ReproReceiver.NOTIFICATION_ID_KEY, notificationIdKey);
        }

        PendingIntent resultPendingIntent = PendingIntent.getActivity(this, identifier, resultIntent, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
        builder.setContentIntent(resultPendingIntent);

        final NotificationManager notificationManager = (NotificationManager)this.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(identifier, builder.build());
    }

    @TargetApi(Build.VERSION_CODES.O)
    private void createOrUpdateChannel() {
        NotificationChannel newChannel = new NotificationChannel(CHANNEL_ID, "Custom Channel", NotificationManager.IMPORTANCE_DEFAULT);
        newChannel.setDescription("");
        newChannel.setShowBadge(true);

        // create or update the Notification channel
        final NotificationManager notificationManager = (NotificationManager)this.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.createNotificationChannel(newChannel);
    }
}
```

```kotlin
private const val TAG = "MessagingService"
private const val CHANNEL_ID = "custom-firebase-messaging-service-channel"

class MyFirebaseMessagingService : FirebaseMessagingService() {

    private val random = Random()

    override fun onNewToken(token: String) {
        Repro.setPushRegistrationID(token)
    }

    override fun onMessageReceived(message: RemoteMessage) {
        val identifier = random.nextInt()
        val data: Map<String, String> = message.data

        // check whether the application should handle this push notification.
        if (!Repro.applicationShouldHandlePushNotification(this, data)) {
            Log.d(TAG, "Ignore push notification: it will be handled by SDK: $data")
            return
        }

        // check whether this push notification is already received.
        if (Repro.isAlreadyReceivedPushNotification(this, data)) {
            Log.d(TAG, "Ignore push notification: it is already received: $data")
            return
        }

        // mark this push notification as "received".
        Log.d(TAG, "Mark push notification as received: $data")
        Repro.markPushNotificationReceived(this, data)

        val messageText = data["message"] ?: "default message"

        val builder = Notification.Builder(this)
            .setContentTitle(resources.getString(R.string.app_name))
            .setContentText(messageText)
            .setSmallIcon(R.mipmap.ic_launcher_round)
            .setAutoCancel(true)

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            createOrUpdateChannel()
            builder.setChannelId(CHANNEL_ID)
        }

        val resultIntent = Intent(this, SomeActivity::class.java)

        val notificationIdKey = data[ReproReceiver.NOTIFICATION_ID_KEY]
        if (notificationIdKey != null) {
            resultIntent.putExtra(ReproReceiver.NOTIFICATION_ID_KEY, notificationIdKey)
        }

        val resultPendingIntent = PendingIntent.getActivity(this, identifier, resultIntent, PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE)

        builder.setContentIntent(resultPendingIntent)

        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

        notificationManager.notify(identifier, builder.build())
    }

    @TargetApi(Build.VERSION_CODES.O)
    private fun createOrUpdateChannel() {
        val newChannel = NotificationChannel(CHANNEL_ID, "Custom Channel", NotificationManager.IMPORTANCE_DEFAULT
        ).apply {
            description = ""
            setShowBadge(true)
        }

        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

        // create or update the Notification channel
        notificationManager.createNotificationChannel(newChannel)
    }
}
```

```dart
// This is a sample that tracks the opening of a message in JSON format.
// For more detailed implementations, see the sample code for the Java version.

// main.dart
FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
    // mark this push notification as "received".
    debugPrint("Mark push notification as received: ${message.data.toString()});
    await Repro.markPushNotificationReceived(message.data);
    ...
});
```

起動されたActivity側では、上述の `resultIntent` にセットしたExtrasからプッシュ通知IDを取得し、 `onResume` で `Repro.trackNotificationOpened` にセットしてください。なおアクティビティのローンチモードが `singleTop` の場合は、 `onNewIntent` で同様にプッシュ通知IDをセットしてください。

```java
public class SomeActivity extends Activity {

  @Override
  protected void onResume() {
      super.onResume();

      Intent intent = getIntent();
      Bundle extras = intent.getExtras();
      if (extras != null && extras.containsKey(io.repro.android.ReproReceiver.NOTIFICATION_ID_KEY)) {
          Repro.trackNotificationOpened(extras.getString(io.repro.android.ReproReceiver.NOTIFICATION_ID_KEY));
      }
  }

  @Override
  protected void onNewIntent(Intent intent) {
      super.onNewIntent(intent);

      Bundle extras = intent.getExtras();
      if (extras != null && extras.containsKey(io.repro.android.ReproReceiver.NOTIFICATION_ID_KEY)) {
          Repro.trackNotificationOpened(extras.getString(io.repro.android.ReproReceiver.NOTIFICATION_ID_KEY));
      }

      this.setIntent(intent);
  }
```

```kotlin
class SomeActivity : Activity() {

    override fun onResume() {
        super.onResume()

        intent?.extras?.let { extras ->
            if (extras.containsKey(io.repro.android.ReproReceiver.NOTIFICATION_ID_KEY)) {
                Repro.trackNotificationOpened(extras.getString(io.repro.android.ReproReceiver.NOTIFICATION_ID_KEY))
            }
        }
    }

    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)

        intent.extras?.let { extras ->
            if (extras.containsKey(io.repro.android.ReproReceiver.NOTIFICATION_ID_KEY)) {
                Repro.trackNotificationOpened(extras.getString(io.repro.android.ReproReceiver.NOTIFICATION_ID_KEY)
                )
            }
        }

        setIntent(intent)
    }
}
```

```dart
// There is no sample code for Flutter in this section.
```

##### NOTE
- プッシュ通知IDは、受信したメッセージのdataから `io.repro.android.ReproReceiver.NOTIFICATION_ID_KEY` というキーで取得できます。

#### 特定のアクティビティの起動時にセッションを開始しないようにする

プッシュ通知の受信を切っ掛けにしてアクティビティを自動起動すると効果測定の結果に影響がある場合など、Reproとのセッションの開始を抑制したい場合があります。
この際には、アクティビティの起動時に使用する `Intent` の `Extras` に `___repro_prevent_session_start___: true` のフラグを設定してください。

```java
public class MyFirebaseMessagingService extends FirebaseMessagingService {

    ...

    @Override
    public void onMessageReceived(RemoteMessage message) {
        ...

        // The existing code
        Intent intent = new Intent(myContext, ActivityStartedByPushNotification.class)

        // Add this code here
        intent.putExtra("___repro_prevent_session_start___", true);

        // The existing code
        startActivity(intent);
    }
}
```

```kotlin
class MyFirebaseMessagingService : FirebaseMessagingService() {

    ...

    override fun onMessageReceived(message: RemoteMessage) {
        ...

        // The existing code
        val intent = Intent(myContext, ActivityStartedByPushNotification::class.java)

        // Add this code here
        intent.putExtra("___repro_prevent_session_start___", true)

        // The existing code
        startActivity(intent)
    }
}
```

```dart
// This implementation is not possible in the Dart language.
```

このフラグを設定することで、アクティビティの起動時にReproとのセッションが開始されなくなります。
起動されたアクティビティから他のアクティビティに遷移する場合やこれ以外のアクティビティの起動時においては、改めてフラグが設定されない限りセッションは開始されます。

##### WARNING
この設定を行うには、アプリケーションに対し Android SDK 5.6.1 以上の導入が必要です。



### オプション：アプリリンクを使用する



端末に表示されたプッシュ通知およびアプリ内メッセージに設定されたリンクをタップした際に実行されるURLには、ユニバーサルリンク（またはアプリリンクと呼ばれる）を指定することが可能です。
（簡単のため、以下ではこれらをユニバーサルリンクと呼びます）

アプリにてユニバーサルリンクの実行時の処理を追加するには、以下の通り実装を行う必要があります。
（ここで設定された動作は、プッシュ通知およびアプリ内メッセージ対し有効となります。）

#### ユニバーサルリンクのURLパターンを登録する

ユニバーサルリンクを利用するためには、まずユニバーサルリンクのURLのパターン（正規表現）を指定する必要があります。

##### NOTE
パターン（正規表現）に合致すると、プッシュ通知の開封時や、アプリ内メッセージの遷移先に設定されたURLに対して、後述のコールバック処理をキックします。

また、アプリ内メッセージでHTMLコンテンツを表示するとき、そのコンテンツ内で発生したリクエストに対してもユニバーサルリンクの判定が行われます。

この指定は、iOSの場合は `AppDelegate` または `.plist` ファイル、Androidの場合は `Application` 継承クラス または `AndroidManifest.xml` ファイルのどちらか一方に記述することで行うことができます。

```objc
// AppDelegate.m

#import <Repro/Repro.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [Repro addOpenUrlFilterRegEx:@"https://example\\.com/page/"];
    [Repro addOpenUrlFilterRegEx:@"your-domain\\.com/.+\?universal=true"];
    ...
}


// .plist file
/*
<dict>
    <key>RPROpenUrlFilterRegExList</key>
    <array>
        <string>https://example\.com/page/</string>
        <string>your-domain\.com/.+\?universal=true</string>
    </array>
    ...
</dict>
*/
```

```java
// MyApplication.java

import io.repro.android.Repro;

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        Repro.addOpenUrlFilterRegEx("https://example\\.com/page/");
        Repro.addOpenUrlFilterRegEx("your-domain\\.com/.+\\?universal=true");
        ...
    }
...
}


// AndroidManifest.xml
// To specify multiple URL patterns, enter them separated by commas.
<application>
    ...
    <meta-data
        android:name="io.repro.android.OpenUrlFilterRegExList"
        android:value="https://example\\.com/page/;your-domain\\.com/.+\\?universal=true">
    </meta-data>
</application>
```

```kotlin
// MyApplication.kt

import io.repro.android.Repro

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        Repro.addOpenUrlFilterRegEx("https://example\\.com/page/")
        Repro.addOpenUrlFilterRegEx("your-domain\\.com/.+\\?universal=true")
        ...
    }
    ...
}


// AndroidManifest.xml
// To specify multiple URL patterns, enter them separated by commas.
<application>
    ...
    <meta-data
        android:name="io.repro.android.OpenUrlFilterRegExList"
        android:value="https://example\\.com/page/;your-domain\\.com/.+\\?universal=true">
    </meta-data>
</application>
```

```swift
// AppDelegate.swift

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
{
    Repro.add(openUrlFilterRegEx: "https://example\\.com/page/")
    Repro.add(openUrlFilterRegEx: "your-domain\\.com/.+\\?universal=true")
    ...
}

// .plist file
/*
<dict>
    <key>RPROpenUrlFilterRegExList</key>
    <array>
        <string>https://example\.com/page/</string>
        <string>your-domain\.com/.+\?universal=true</string>
    </array>
    ...
</dict>
*/
```

```dart
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

```csharp
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

```cpp
// YourAppNameScene.cpp

bool YourAppName::init() {
    ReproCpp::addOpenUrlFilterRegEx("https://example\\.com/page/");
    ReproCpp::addOpenUrlFilterRegEx("your-domain\\.com/.+\\?universal=true");
    ...
}
```

```js-cordova
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

```js-react-native
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

##### WARNING
ユニバーサルリンクとして設定するURLパターンは、可能な限り **ドメインとパスまで含めて具体的に指定** し、 **全て小文字で指定** してください。

もし、 https のようにスキームのみを指定した場合、アプリ内メッセージで表示された画面内で実行されたスクリプトなどによるリクエストもユニバーサルリンクと誤って判定され、意図しないタイミングでコールバック処理が実行される可能性があります。

また、URLパターンのスキーム/ドメイン部分に大文字を使用した場合、HTMLアプリ内メッセージで表示したボタンからユニバーサルリンクを使って遷移させようとするときに、スキーム/ドメイン部分が自動的に小文字に変換されて処理されます。パターン（正規表現）に一致せず、意図したタイミングでコールバック処理が実行されない可能性があります。

#### ユニバーサルリンク実行時の処理を登録する

次に、ユニバーサルリンクが実行された際に動作するコールバック処理を実装します。
処理内には、例えばURLのパターンに応じて画面遷移を行う動作などを記述します。

```objc
#import <Repro/Repro.h>

...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [Repro setOpenUrlCallback:^(NSURL *url) {
        if ([url.host isEqualToString:@"example.com"]) {
            // In case of your universal link perform navigation, present content, ...
            handleUniversalLink(url);
        }
    }];

    ...
    [Repro setup:@"YOUR_APP_TOKEN"];
    ...
}
```

```swift
// Set a callback that is executed everytime an URL is about to be opened
Repro.setOpenUrlCallback { url in
    if url.host == "example.com" {
        // In case of your universal link perform navigation, present content, ...
        handleUniversalLink(url)
    }
}
...
Repro.setup(token: "YOUR_APP_TOKEN")
...
```

```java
import io.repro.android.Repro;

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        // In order to execute a callback when a push notification is tapped,
        // the callback must be set in Application, not Activity.
        Repro.setOpenUrlCallback(new Repro.OpenUrlCallback() {
            // ** This callback method is executed in the main thread **
            @Override
            public void onOpened(Uri uri) {
                if ("example.com".equals(uri.getHost())) {
                    // In case of your universal link perform navigation, present content, ...
                }
            }
        });

        ...
        Repro.setup(this, YOUR_APP_TOKEN);
        ...
    }
    ...
}
```

```kotlin
import io.repro.android.Repro

class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        // In order to execute a callback when a push notification is tapped,
        // the callback must be set in Application, not Activity.
        Repro.setOpenUrlCallback { uri ->
            // ** This callback method is executed in the main thread **
            if (uri.host == "example.com") {
                // In case of your universal link perform navigation, present content, ...
            }
        }

        ...
        Repro.setup(this, "YOUR_APP_TOKEN")
        ...
    }
    ...
}
```

```dart
Repro.setOpenUrlCallback((uri) { // uri is of type Uri
   debugPrint("Universal Link Callback Handler received: " + uri.toString());
});
```

```csharp
// Somewhere before Repro.Setup(...)
Repro.SetOpenUrlCallback(uri => // uri is of type Uri
{
    Debug.Log("Universal Link Callback Handler received: " + uri.ToString());
});
```

```cpp
bool YourAppName::init() {
    ReproCpp::addOpenUrlFilterRegEx(...);

    ReproCpp::setOpenUrlCallback([](const char *url) {
        if (strcmp(url, "example.com") == 0) {
            // In case of your universal link perform navigation, present content, ...
        }
    });

    ReproCpp::setup("YOUR_APP_TOKEN")
    ...
}
```

```js-cordova
Repro.setOpenUrlCallback(function(url) { // url is of type String
    alert('Universal Link Callback Handler received: ' + url);
    if (url.includes("http://example.org")) {
        // In case of your universal link perform navigation, present content, ...
    }
});
```

```js-react-native
Repro.setOpenUrlCallback( (url) => {  // url is of type String
    console.log('Universal Link Callback Handler received: ' + url);
    if (url.includes("http://example.org")) {
        // In case of your universal link perform navigation, present content, ...
    }
});
```

---

## Reproからプッシュ通知を受信した際、デフォルトでバナー表示されますか？

Reproから配信したプッシュ通知は、OSによって表示方法が異なります。

### SDK実装完了後の挙動

**iOS:**

プッシュ通知を受信すると、バナーとして表示されます。あわせて、通知センターに登録されます。
アプリがフォアグラウンド状態にある場合、デフォルトでは表示されません。

**Android:**

プッシュ通知を受信すると、通知ドロワーにのみ表示されます。
画面上部に通知内容がバナー表示される仕様はありません。バナー表示されるプッシュ通知はヘッドアップ通知と呼ばれます。

### OSごとの通知表示の違い

**iOS:**

ユーザーの通知設定で許諾はOnのまま、バナー表示のみを拒否できます。
プッシュ通知の実装が正常に完了していても画面上部に表示されない場合があります。

また、デフォルトではフォアグラウンド状態の通知は行われませんが、実装によって表示することができます。
[userNotificationCenter(_:willPresent:withCompletionHandler:)](https://developer.apple.com/documentation/usernotifications/unusernotificationcenterdelegate/usernotificationcenter(_:willpresent:withcompletionhandler:))
を用い、バナー表示させると挙動が異なります。

**Android:**

通知ドロワーにのみ表示され、画面上部には表示されません。
そのため、ReproからAndroid端末へ配信したプッシュ通知が画面上部に表示されていなくても、通知ドロワーに入っていればプッシュ通知の実装は正常に行われています。

もし、バナー表示されるヘッドアップ通知を行う場合は、アプリ側で通知チャンネルの設定などを含む追加実装が必要です。

### Androidでヘッドアップ通知を表示する方法

#### 1.カスタム(JSON)形式で配信する

Reproから配信する際に、[メッセージ(プッシュ通知「カスタム(JSON)」)](https://docs.repro.io/ja/dashboard/campaign/push-notification.md#push-notification-custom-json-format) 形式を使用してください。

##### NOTE
[メッセージ(プッシュ通知「スタンダード」)](https://docs.repro.io/ja/dashboard/campaign/push-notification.md#push-notification-standard-format) 形式でヘッドアップ通知を実現することはできません。

#### 2.通知チャンネルを新たに作成する

ヘッドアップ通知を実現するには、スタンダード形式でRepro SDKが使用する通知チャンネルとは別の通知チャンネルを用意する必要があります。

スタンダード形式でプッシュ通知を配信した場合、Repro SDKが自動でプッシュ通知をハンドリングします。
そのとき、ReproSDKは受信した通知を `AndroidManifest` に指定された通知チャンネルに割り当て、重要度（importance）をデフォルトで `IMPORTANCE_DEFAULT` に設定します。

参考：[通知チャンネルの設定](https://docs.repro.io/ja/dev/sdk/push-notification/android.md#notification-channel-setting)

スタンダード形式のプッシュ通知を配信するものと別の通知チャンネルを用意し、チャンネルの重要度を `IMPORTANCE_HIGH` に設定してください。

Reproから配信した通知をこのチャンネルに割り当てる通知としてハンドリングすることで、ヘッドアップ通知として表示することができます。

実装にあたって不明点や問題が発生した場合は、画面右下のチャットサポートよりお問い合わせください。

---

csharp

## プッシュ通知 (Unity)

### プッシュ通知の設定

[APNs証明書の設定 (iOS)](https://docs.repro.io/ja/dev/sdk/push-notification/setup-ios.md) と [FCMの設定 (Android)](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md) を参照し、設定してください。

### Firebase Unity SDKを導入する

[Firebaseの公式ドキュメント](https://firebase.google.com/docs/unity/setup?hl=ja) を参照し **FirebaseMessaging.unitypackage** をインポートしてください。

##### WARNING
Repro Unity Package 6.5.0 以下、あるいは Firebase Cloud Messaging for Unity 7.2.0 以下を使用される場合には **FirebaseInstanceId.unitypackage** を追加でインポートしてください。

##### WARNING
Firebaseのパッケージをインポートした後、 [導入時に修正したAndroidManifest.xml](https://docs.repro.io/ja/dev/sdk/getstarted/unity.md#unity-setup-application) がFirebaseの設定で上書きされることがあります。そのため、インポート後にもう一度 `AndroidManifest.xml` を修正してください。

### iOSプラットフォーム

iOSプラットフォームでは、ご使用のUnityのバージョンによって実装方法が異なります。
Unityのバージョンをご確認の上、実装方法を選択してください。

#### デバイストークンをReproに送信 (Unity 2019.4 未満の場合)

ここではUnityの公式APIを利用して実装を行います。
公式APIの詳細は  [こちら](https://docs.unity3d.com/2019.3/Documentation/ScriptReference/iOS.NotificationServices.RegisterForNotifications.html)  を参照してください。

XcodeのCapabilitiesにてPush NotificationsをONにします。



`MonoBehaviour` を継承したクラスの `Start()` メソッドにてAPNsへの端末登録処理を行います。また同じクラスの `Update()` メソッドにてReproにデバイストークンをセットします。

```csharp
using UnityEngine;

#if UNITY_IOS
using NotificationServices = UnityEngine.iOS.NotificationServices;
using NotificationType = UnityEngine.iOS.NotificationType;
#endif

public class MyBehaviour : MonoBehaviour {

  bool tokenSent;

  void Start () {
    ...

#if UNITY_IOS
    tokenSent = false;
    NotificationServices.RegisterForNotifications(
        NotificationType.Alert |
        NotificationType.Badge |
        NotificationType.Sound);
#endif

    ...
  }

  void Update () {
#if UNITY_IOS
    // Send device token to Repro
    if (!tokenSent) {
      byte[] token = NotificationServices.deviceToken;
      if (token != null) {
        string hexToken = System.BitConverter.ToString(token).Replace("-", "");
        Repro.SetPushDeviceToken(hexToken);
        tokenSent = true;
      }
    }
#endif
  }
}
```

#### デバイストークンをReproに送信 (Unity 2019.4 以上の場合)

ここでは [Mobile Notifications package](https://docs.unity3d.com/Packages/com.unity.mobile.notifications@2.3/manual/index.html) を用いてプッシュ通知の実装を行います。

まず、Unity Package Manager を用いてプロジェクトに [Mobile Notifications package](https://docs.unity3d.com/Packages/com.unity.mobile.notifications@2.3/manual/index.html) を導入してください。
導入方法は [こちら](https://docs.unity3d.com/Packages/com.unity.mobile.notifications@2.3/manual/index.html#install-the-package) を参照してください。

次に、Unity Editorの **Project Settings > Mobile Notifications** にて `Enable Push Notifications` を有効にしてください。



最後に、以下のように `MonoBehavior` を継承したクラスで `Repro.SetPushDeviceToken()` にデバイストークンをセットします。

```csharp
#if UNITY_IOS
using Unity.Notifications.iOS;
#endif
...

public class MyBehaviour : MonoBehaviour {

    public void Start()
    {
        ...
#if UNITY_IOS
        StartCoroutine(RequestAuthorization());
#endif
    }

#if UNITY_IOS
    IEnumerator RequestAuthorization()
    {
        var authorizationOption = AuthorizationOption.Alert | AuthorizationOption.Badge | AuthorizationOption.Sound;
        using (var req = new AuthorizationRequest(authorizationOption, true))
        {
            while (!req.IsFinished)
            {
                yield return null;
            };
            Repro.SetPushDeviceToken(req.DeviceToken);
        }
    }
#endif
}
```

設定の詳細は [こちら](https://docs.unity3d.com/Packages/com.unity.mobile.notifications@2.3/manual/Settings.html) を参照してください。

### Androidプラットフォーム

#### `AndroidManifest.xml` ファイルを編集する

##### Receiverの登録

以下のXML中の "YOUR_PACKAGE_NAME" をアプリケーションのパッケージ名に置き換え、AndroidManifest.xmlの `<application>` タグの中に追加してください。

```xml
<receiver
    android:name="io.repro.android.ReproReceiver"
    android:exported="true"
    android:permission="com.google.android.c2dm.permission.SEND">
    <intent-filter>
        <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        <category android:name="YOUR_PACKAGE_NAME" />
    </intent-filter>
</receiver>
```

##### 通知チャンネルの設定

Android Oにて、ユーザーが通知を管理できるように通知チャンネルが導入されました。

Repro SDKで利用する通知チャンネルの設定を行うには、「ID」「名前」「ユーザー向けの説明」「badgeの表示有無」を指定する必要があります。
以下のXML中の `value`, `resource` を設定したい値に書き換え、AndroidManifest.xmlの `<application>` タグの中に追加してください。
IDと名前の指定は必須、その他は省略可能です。「ユーザー向けの説明」省略時は空文字列、「badgeの表示有無」省略時はbadgeの表示有りとなります。

##### WARNING
- アプリのtargetSDKVersionが26以上かつAndroid O以降の機種で動作させる場合、IDと名前が指定されていなければSDKはReproからのプッシュ通知を表示いたしませんのでご注意ください。
- `ChannelId` に指定する値は、整数や小数ではなく `test ID` のような文字列を指定してください。文字列以外の値を指定するとチャンネルIDの指定がうまく動作せず、プッシュ通知が表示されません。
- `ChannelName` と `ChannelDescription` の設定は `android:resource` 属性を使用してください。

```xml
<meta-data
    android:name="io.repro.android.PushNotification.ChannelId"
    android:value="YOUR_CHANNEL_ID">
</meta-data>

<meta-data
    android:name="io.repro.android.PushNotification.ChannelName"
    android:resource="@string/YOUR_CHANNEL_NAME">
</meta-data>

<meta-data
    android:name="io.repro.android.PushNotification.ChannelDescription"
    android:resource="@string/YOUR_CHANNEL_DESCRIPTION">
</meta-data>

<meta-data
    android:name="io.repro.android.PushNotification.ShowBadge"
    android:value="true">
</meta-data>
```

指定されたIDの通知チャンネルが存在しない場合はAndroidManifest.xmlの指定を基にSDKが自動で作成し、指定されたIDの通知チャンネルが存在する場合は既存のものを利用します。

既存のものを利用する場合、SDKは「名前」、「ユーザー向けの説明」及び「チャンネルの重要度」を更新します。

また、アプリのtargetSDKVersionが25以下の場合、あるいは、Android O未満の機種の場合は、SDKは上記の通知チャンネルに関する設定を無視します。

##### NOTE
通知チャンネルはAndroid Oで導入されたAndroidの標準機能です。通知チャンネルの詳細は [こちら](https://developer.android.com/preview/features/notification-channels.html?hl=ja) をご覧ください。

##### アイコンと背景色のカスタマイズ

Android5.0以降の機種で、通知エリアに表示されるアイコンとその背景色をカスタマイズする場合は、以下のXMLをAndroidManifest.xmlの `<application>` タグの中に追加してください。Android5.0未満の機種では以下の設定は無視され、通知エリアにはアプリケーションのアイコンおよびシステムデフォルトの背景色が使用されます。

```xml
<meta-data
    android:name="io.repro.android.PushNotification.SmallIcon"
    android:resource="@drawable/YOUR_ICON_ID">
</meta-data>

<meta-data
    android:name="io.repro.android.PushNotification.AccentColor"
    android:resource="@color/YOUR_COLOR_ID">
</meta-data>
```

#### Registration IDをReproに送信

MonoBehaviour を継承したクラスの Start() メソッドにて、 `Repro.EnablePushNotification()` を呼び出してください。

Registration IDが更新された時は [こちら](https://firebase.google.com/docs/cloud-messaging/unity/client#initialize) の方法で取得可能です。取得したRegistration IDを `Repro.SetPushRegistrationID()` でセットしてください。

```csharp
using UnityEngine;

public class MyBehaviour : MonoBehaviour {

  void Start () {
    ...

#if UNITY_ANDROID
    Repro.EnablePushNotification();
#endif

#if UNITY_ANDROID
    Firebase.Messaging.FirebaseMessaging.TokenReceived += OnTokenReceived;
    Firebase.Messaging.FirebaseMessaging.MessageReceived += OnMessageReceived;
#endif

    ...
  }

#if UNITY_ANDROID
  public void OnTokenReceived(object sender, Firebase.Messaging.TokenReceivedEventArgs token) {
    Repro.SetPushRegistrationID(token.Token);
  }

  public void OnMessageReceived(object sender, Firebase.Messaging.MessageReceivedEventArgs e) {
    ...
  }
#endif
}
```

上記の実装が終わったら、 [プッシュ通知作成画面](https://docs.repro.io/ja/dashboard/campaign/push-notification.md#push-create-message) をご覧ください。

#### プッシュ通知受信時の動作をカスタマイズする

Repro Unity Packageは [オプション：プッシュ通知受信時の動作をカスタマイズする](android.html#customize-receiver) に示すプッシュ通知受信時の動作のカスタマイズには対応しておりません。ご了承ください。



### オプション：ユニバーサルリンク/アプリリンクを使用する



端末に表示されたプッシュ通知およびアプリ内メッセージに設定されたリンクをタップした際に実行されるURLには、ユニバーサルリンク（またはアプリリンクと呼ばれる）を指定することが可能です。
（簡単のため、以下ではこれらをユニバーサルリンクと呼びます）

アプリにてユニバーサルリンクの実行時の処理を追加するには、以下の通り実装を行う必要があります。
（ここで設定された動作は、プッシュ通知およびアプリ内メッセージ対し有効となります。）

#### ユニバーサルリンクのURLパターンを登録する

ユニバーサルリンクを利用するためには、まずユニバーサルリンクのURLのパターン（正規表現）を指定する必要があります。

##### NOTE
パターン（正規表現）に合致すると、プッシュ通知の開封時や、アプリ内メッセージの遷移先に設定されたURLに対して、後述のコールバック処理をキックします。

また、アプリ内メッセージでHTMLコンテンツを表示するとき、そのコンテンツ内で発生したリクエストに対してもユニバーサルリンクの判定が行われます。

この指定は、iOSの場合は `AppDelegate` または `.plist` ファイル、Androidの場合は `Application` 継承クラス または `AndroidManifest.xml` ファイルのどちらか一方に記述することで行うことができます。

```objc
// AppDelegate.m

#import <Repro/Repro.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [Repro addOpenUrlFilterRegEx:@"https://example\\.com/page/"];
    [Repro addOpenUrlFilterRegEx:@"your-domain\\.com/.+\?universal=true"];
    ...
}


// .plist file
/*
<dict>
    <key>RPROpenUrlFilterRegExList</key>
    <array>
        <string>https://example\.com/page/</string>
        <string>your-domain\.com/.+\?universal=true</string>
    </array>
    ...
</dict>
*/
```

```java
// MyApplication.java

import io.repro.android.Repro;

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        Repro.addOpenUrlFilterRegEx("https://example\\.com/page/");
        Repro.addOpenUrlFilterRegEx("your-domain\\.com/.+\\?universal=true");
        ...
    }
...
}


// AndroidManifest.xml
// To specify multiple URL patterns, enter them separated by commas.
<application>
    ...
    <meta-data
        android:name="io.repro.android.OpenUrlFilterRegExList"
        android:value="https://example\\.com/page/;your-domain\\.com/.+\\?universal=true">
    </meta-data>
</application>
```

```kotlin
// MyApplication.kt

import io.repro.android.Repro

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        Repro.addOpenUrlFilterRegEx("https://example\\.com/page/")
        Repro.addOpenUrlFilterRegEx("your-domain\\.com/.+\\?universal=true")
        ...
    }
    ...
}


// AndroidManifest.xml
// To specify multiple URL patterns, enter them separated by commas.
<application>
    ...
    <meta-data
        android:name="io.repro.android.OpenUrlFilterRegExList"
        android:value="https://example\\.com/page/;your-domain\\.com/.+\\?universal=true">
    </meta-data>
</application>
```

```swift
// AppDelegate.swift

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
{
    Repro.add(openUrlFilterRegEx: "https://example\\.com/page/")
    Repro.add(openUrlFilterRegEx: "your-domain\\.com/.+\\?universal=true")
    ...
}

// .plist file
/*
<dict>
    <key>RPROpenUrlFilterRegExList</key>
    <array>
        <string>https://example\.com/page/</string>
        <string>your-domain\.com/.+\?universal=true</string>
    </array>
    ...
</dict>
*/
```

```dart
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

```csharp
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

```cpp
// YourAppNameScene.cpp

bool YourAppName::init() {
    ReproCpp::addOpenUrlFilterRegEx("https://example\\.com/page/");
    ReproCpp::addOpenUrlFilterRegEx("your-domain\\.com/.+\\?universal=true");
    ...
}
```

```js-cordova
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

```js-react-native
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

##### WARNING
ユニバーサルリンクとして設定するURLパターンは、可能な限り **ドメインとパスまで含めて具体的に指定** し、 **全て小文字で指定** してください。

もし、 https のようにスキームのみを指定した場合、アプリ内メッセージで表示された画面内で実行されたスクリプトなどによるリクエストもユニバーサルリンクと誤って判定され、意図しないタイミングでコールバック処理が実行される可能性があります。

また、URLパターンのスキーム/ドメイン部分に大文字を使用した場合、HTMLアプリ内メッセージで表示したボタンからユニバーサルリンクを使って遷移させようとするときに、スキーム/ドメイン部分が自動的に小文字に変換されて処理されます。パターン（正規表現）に一致せず、意図したタイミングでコールバック処理が実行されない可能性があります。

#### ユニバーサルリンク実行時の処理を登録する

次に、ユニバーサルリンクが実行された際に動作するコールバック処理を実装します。
処理内には、例えばURLのパターンに応じて画面遷移を行う動作などを記述します。

```objc
#import <Repro/Repro.h>

...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [Repro setOpenUrlCallback:^(NSURL *url) {
        if ([url.host isEqualToString:@"example.com"]) {
            // In case of your universal link perform navigation, present content, ...
            handleUniversalLink(url);
        }
    }];

    ...
    [Repro setup:@"YOUR_APP_TOKEN"];
    ...
}
```

```swift
// Set a callback that is executed everytime an URL is about to be opened
Repro.setOpenUrlCallback { url in
    if url.host == "example.com" {
        // In case of your universal link perform navigation, present content, ...
        handleUniversalLink(url)
    }
}
...
Repro.setup(token: "YOUR_APP_TOKEN")
...
```

```java
import io.repro.android.Repro;

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        // In order to execute a callback when a push notification is tapped,
        // the callback must be set in Application, not Activity.
        Repro.setOpenUrlCallback(new Repro.OpenUrlCallback() {
            // ** This callback method is executed in the main thread **
            @Override
            public void onOpened(Uri uri) {
                if ("example.com".equals(uri.getHost())) {
                    // In case of your universal link perform navigation, present content, ...
                }
            }
        });

        ...
        Repro.setup(this, YOUR_APP_TOKEN);
        ...
    }
    ...
}
```

```kotlin
import io.repro.android.Repro

class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        // In order to execute a callback when a push notification is tapped,
        // the callback must be set in Application, not Activity.
        Repro.setOpenUrlCallback { uri ->
            // ** This callback method is executed in the main thread **
            if (uri.host == "example.com") {
                // In case of your universal link perform navigation, present content, ...
            }
        }

        ...
        Repro.setup(this, "YOUR_APP_TOKEN")
        ...
    }
    ...
}
```

```dart
Repro.setOpenUrlCallback((uri) { // uri is of type Uri
   debugPrint("Universal Link Callback Handler received: " + uri.toString());
});
```

```csharp
// Somewhere before Repro.Setup(...)
Repro.SetOpenUrlCallback(uri => // uri is of type Uri
{
    Debug.Log("Universal Link Callback Handler received: " + uri.ToString());
});
```

```cpp
bool YourAppName::init() {
    ReproCpp::addOpenUrlFilterRegEx(...);

    ReproCpp::setOpenUrlCallback([](const char *url) {
        if (strcmp(url, "example.com") == 0) {
            // In case of your universal link perform navigation, present content, ...
        }
    });

    ReproCpp::setup("YOUR_APP_TOKEN")
    ...
}
```

```js-cordova
Repro.setOpenUrlCallback(function(url) { // url is of type String
    alert('Universal Link Callback Handler received: ' + url);
    if (url.includes("http://example.org")) {
        // In case of your universal link perform navigation, present content, ...
    }
});
```

```js-react-native
Repro.setOpenUrlCallback( (url) => {  // url is of type String
    console.log('Universal Link Callback Handler received: ' + url);
    if (url.includes("http://example.org")) {
        // In case of your universal link perform navigation, present content, ...
    }
});
```

---

csharp

## 導入: Unity

### Unity Packageのインストール

- 最新の [Repro-Unity-SDK](https://github.com/reproio/repro-unity-sdk/releases/latest) をダウンロードしてください
- `Repro.unitypackage` を **Asset > Import Package > Custom Package...** からImportしてください

古いバージョンのUnityを利用している場合、下記のようなエラーが発生しAndroidManifest.xmlのマージに失敗する場合があります。マージに失敗した場合は [こちら](https://docs.repro.io/ja/dev/sdk/getstarted/old-version-unity.md) をご覧ください。

```
CommandInvokationFailure: Unable to merge android manifests. See the Console for more details.
/Library/Java/JavaVirtualMachines/jdk1.8.0_51.jdk/Contents/Home/bin/java -Xmx2048M -Dcom.android.sdkmanager.toolsdir="/Users/john/Library/Android/sdk.old/tools" -Dfile.encoding=UTF8 -jar "/Applications/Unity5.4.5/PlaybackEngines/AndroidPlayer/Tools/sdktools.jar" -

stderr[

]
stdout[
[Temp/StagingArea/AndroidManifest-main.xml:25, /Users/john/sample/unity5/Temp/StagingArea/android-libraries/repro-android-sdk-2.7.9/AndroidManifest.xml:11] Skipping identical /manifest/application/receiver[@name=com.sample.notification.IntentHandler] element.
Warning: [Temp/StagingArea/AndroidManifest-main.xml:31, /Users/john/sample/unity5/Temp/StagingArea/android-libraries/repro-android-sdk-2.7.9/AndroidManifest.xml:3] Main manifest has <uses-sdk android:targetSdkVersion='25'> but library uses targetSdkVersion='26'
]
```



### Applicationクラスを指定する (Android)

##### NOTE
この手順はターゲットプラットフォームがAndroidの場合のみ必要です。

**独自のApplicationクラスを使っていない場合:**

**application** エレメントの **android:name** 属性に **io.repro.android.UnityApplication** を指定してください。

```diff
+   <application android:name="io.repro.android.UnityApplication" ...
```



**独自のApplicationクラスを使っている場合:**

1. 解凍したフォルダの **repro-unity-bridge.jar** をプロジェクトの **libs** フォルダにコピーしてください。
2. プロジェクトの **build.gradle** を以下のように編集して、**repro-unity-bridge.jar** への依存をプロジェクトに追加してください。

```diff
 dependencies {
     ...
+    provided fileTree(dir: 'libs', include: ['*.jar'])
     ...
 }
```

1. 独自のApplicationクラスの `onCreate` にて `io.repro.android.UnityBridge.setupWithoutToken(Application)` を呼び出してください。

```diff
 public class MyApplication extends Application {
     @Override
     public void onCreate() {
         super.onCreate();
         ...
+        io.repro.android.UnityBridge.setupWithoutToken(this);
         ...
     }
 }
```

### セットアップ

Reproの [セッション](https://docs.repro.io/ja/dev/sdk/session.md) を開始するUnity Scriptを作成し、アプリの最初のシーンのメインカメラなどにアタッチしてください。

`YOUR_APP_TOKEN` には管理画面の **設定 > プロジェクト設定 > 認証情報** に記載されている **SDK トークン** を設定してください。

```csharp
using UnityEngine;

public class MyBehaviour : MonoBehaviour {

    void Start () {

        ...

        // Setup Repro
        Repro.Setup ("YOUR_APP_TOKEN");

        ...
    }
}
```

SDKが収集した情報は定期的にサーバーにアップロードされます。

### イベントをトラックする

意味のある分析や、マーケティング施策を実施するためには、適切なユーザーグループを絞り込むことが重要です。イベントをトラックしてユーザーの行動を記録することにより、管理画面上で目的に応じた適切なユーザーグループを選択することができるようになります。

イベントを用いたユーザーグループ指定の例:

- [キャンペーンの作成画面で、イベントやユーザープロフィールを組み合わせて、配信対象となるユーザーグループを指定する](https://docs.repro.io/ja/dashboard/campaign/target.md)

どういうイベントをとるべきかわからない場合は、まず各画面の表示時にイベントをとってみることをおすすめします。

例:

```objc
@implementation MainViewController

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [Repro track:@"MainViewController" properties:nil];

    ...
}
```

```swift
class MainViewController: UIViewController {

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        Repro.track(event: "MainViewController", properties: [:])

        ...
    }
```

```java
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onResume() {
        super.onResume();
        Repro.track("MainActivity");

        ...
    }
}
```

```kotlin
class MainActivity : AppCompatActivity() {

    override fun onResume() {
        super.onResume()
        Repro.track("MainActivity")

        ...
    }
}
```

```cpp
#include "ReproCpp.h"

...

ReproCpp::track("Initialized");
```

```csharp
Repro.Track ("Initialized");
```

```js-cordova
// Will be written later
```

```js-react-native
class MainScreen extends React.Component {

    componentDidMount() {
        Repro.track("MainScreen", {});
    }

    ...
 }
```

```js-expo
import Repro from 'react-native-repro';

...

Repro.track("MainScreen", {});
```

```dart
import 'package:repro_flutter/repro.dart';

...

await Repro.track("Initialized");
```

### ユーザーIDをセットする

Repro では分析結果はユーザー単位で集計しています。ユーザーIDをセットすることにより、下記のメリットがあります:

- 複数のデバイスを使っているユーザーを同一視できる
- キャンペーンの配信対象の抽出がより精緻になる

詳しくは [こちら](https://docs.repro.io/ja/dev/sdk/user-id.md) をご覧ください。

### プッシュ通知を配信する

Reproでは、管理画面もしくはAPIからプッシュ通知配信をすることができます。プッシュ通知配信をするための実装は [こちら](https://docs.repro.io/ja/dev/sdk/push-notification/index.md) をご覧ください。

### Next...

その他の機能についての詳細は、以下をご覧ください。

- [セッション・ライフサイクル](https://docs.repro.io/ja/dev/sdk/session.md)
- [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md)
- [ユーザーID](https://docs.repro.io/ja/dev/sdk/user-id.md)
- [デバイスID](https://docs.repro.io/ja/dev/sdk/device-id.md)
- [ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md)
- [WebView](https://docs.repro.io/ja/dev/sdk/webview.md)
- [オプトアウト機能](https://docs.repro.io/ja/dev/sdk/optout/index.md)
- [アプリ内メッセージ](https://docs.repro.io/ja/dev/sdk/in-app-message.md)
- [プッシュ通知](https://docs.repro.io/ja/dev/sdk/push-notification/index.md)
- [Adjustで取得したアトリビューションデータをReproにセットする](https://docs.repro.io/ja/dev/sdk/integrate-adjust.md)
- [AppsFlyerで取得したアトリビューションデータをReproにセットする](https://docs.repro.io/ja/dev/sdk/integrate-appsflyer.md)

---

## 古いUnityを利用したAndroidアプリビルドでAndroidManifest.xmlのマージに失敗する原因と対処方法

古いUnityでAndroidアプリをビルドをする際に、次のようなエラーによりAndroidManifest.xmlのマージに失敗することがあります。

```
CommandInvokationFailure: Unable to merge android manifests. See the Console for more details.
/Library/Java/JavaVirtualMachines/jdk1.8.0_51.jdk/Contents/Home/bin/java -Xmx2048M -Dcom.android.sdkmanager.toolsdir="/Users/john/Library/Android/sdk.old/tools" -Dfile.encoding=UTF8 -jar "/Applications/Unity5.4.5/PlaybackEngines/AndroidPlayer/Tools/sdktools.jar" -

stderr[

]
stdout[
[Temp/StagingArea/AndroidManifest-main.xml:25, /Users/john/sample/unity5/Temp/StagingArea/android-libraries/repro-android-sdk-2.7.9/AndroidManifest.xml:11] Skipping identical /manifest/application/receiver[@name=com.sample.notification.IntentHandler] element.
Warning: [Temp/StagingArea/AndroidManifest-main.xml:31, /Users/john/sample/unity5/Temp/StagingArea/android-libraries/repro-android-sdk-2.7.9/AndroidManifest.xml:3] Main manifest has <uses-sdk android:targetSdkVersion='25'> but library uses targetSdkVersion='26'
]
```

**原因**

`Repro.unitypackage` に含まれるAARファイルのAndroidManifest.xmlでは、 `uses-sdk` タグを使ってtargetSdkVersionを指定しています。通常はアプリのtargetSdkVersionが優先されますが、古いUnityではAARとアプリのtargetSdkVersionが異なる場合にビルドエラーが発生します。

##### NOTE
AndroidManifest.xmlのマージエラーについて、詳しくは [こちら](https://answers.unity.com/questions/1283008/android-unable-to-merge-android-manifest-error.html) をご覧ください。

この問題は、以下の対策が可能です。

**対策**

1. Unity PackageをImportしたプロジェクトから、 `Assets > Plugins > Android > libs` にあるAARファイルを削除
2. repro-unity-sdkにある `removed-uses-sdk-aar` フォルダのAARファイルを `Assets > Plugins > Android > libs` へコピー



この時、コピーしたAARファイルのAndroidManifest.xmlでは `uses-sdk` タグが除外されているため、Android SDK Toolの機能により以下のパーミッションが追加されることがあります。

- `READ_PHONE_STATE`
- `WRITE_EXTERNAL_STORAGE`
- `READ_EXTERNAL_STORAGE`

このうちアプリで使っていないパーミッションを除外したい場合は、アプリのAndroidManifest.xmlに以下の該当する `uses-permission` タグを追加してください。

```diff
<application ...

+    <uses-permission android:name="android.permission.READ_PHONE_STATE" tools:node="remove" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="remove" />
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" tools:node="remove" />

...

</application>
```

##### NOTE
パーミッションが自動で追加される条件について、詳しくは [こちら](https://developer.android.com/studio/build/manifest-merge#implicit_system_permissions) を参照してください。

---

## セッション・ライフサイクル

### iOS/Android

Reproでは、アプリが起動してからバックグラウンドへ移行するまでを１セッションとして扱います。トラッキングされたイベントは、全ていずれかのセッションにひもづけられます。

#### セッションの期間

セッションの期間は、ユーザーの操作に依存します。期間の上限や下限はありません。

#### セッションの開始

セッションの開始方法には２つのパターンがあります。

##### アプリが初期状態で起動する場合

以下の場合、アプリケーションが初期状態で起動します。

1. 電源が入った後、一度も起動されていない場合
2. ユーザーがマルチタスク画面でアプリを明示的に停止した場合
3. OSによって自動的に停止されてから起動した場合

この場合、セッションを開始するのは、 `setup` を呼び出した後です。 `setup` が呼ばれると、SDKはReproのサーバーと通信し、トラッキングなどに関する設定情報を取得します。設定でReproの機能が有効になっている場合に、セッションを開始します。

##### アプリが再開する場合

アプリがバックグラウンドに移行した後、OSによって停止させられる前に、マルチタスク画面から立ち上げられると、アプリが途中から始まります。

この場合、iOSの `AppDelegate::applicationDidFinishLaunching:` およびAndroidの `Application#onCreate` が呼ばれないため、`setup` も呼ばれませんが、SDKはアプリの再開を自動的に検出し、新規にセッションを開始します。



#### セッションの終了

セッションが終了するのは、ホームボタンを押す、 通知センターから別のアプリを立ち上げるなどの操作によって、アプリケーションがバックグラウンドに移行した時です。

なお、ユーザーがコントロールセンターや通知センターを開いただけの場合、セッションは終了しません。

---

## 配信対象を選択する



イベントやユーザープロフィール、全ユーザーといったセグメンテーションフィルターをつかって、配信対象となるユーザーを指定できます。各フィルターは **and** 、 **and not** 、 **or** を使って、最大5個まで組み合わせられます。

- **and**: 指定した条件を全て満たすユーザーが対象になります
- **and not**: 指定した条件にあてはまるユーザーが対象から除外されます
- **or**: 指定した複数の条件のどれかにあてはまるユーザーが対象になります

例えば:

- 3日前にアプリを使用して、その後2日間アプリを使っていないユーザーへ配信する場合


- 性別が女性で直近3日以内にイベントAかイベントBのどちらかを実行したユーザーへ配信する場合



### オーディエンスでフィルタリング

[オーディエンス](https://docs.repro.io/ja/dashboard/campaign/audience.md) で作成したセグメンテーションを利用することができます。

##### NOTE
- フィルターオーディエンス: 他のフィルタリング条件と組み合わせることはできません。
- インポートオーディエンス: 他のフィルタリング条件と組み合わせることができます。

### イベントでフィルタリング

[イベント](https://docs.repro.io/ja/dev/sdk/tracking.md) を実行したユーザーをセグメンテーションすることができます。実行した期間や回数を指定することができます。

### イベントプロパティでフィルタリング

[イベント](https://docs.repro.io/ja/dev/sdk/tracking.md) を実行したユーザーのうち、実行されたイベントに付帯するプロパティにもとづいてユーザーをセグメンテーションすることができます。プロパティの名前や値、実行した期間や回数を指定することができます。

### ユーザープロフィールでフィルタリング

[ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md) に登録されている情報にもとづいてユーザーをセグメンテーションすることができます。SDKでプロフィールの型に数値を指定している場合、「以上、以下、より大きい、より小さい」などをつかって、値を比較する条件を指定できます。文字を指定している場合、「一致する、一致しない、含む」などをつかって、条件を指定できます。日付を指定している場合、「◯日前以前、◯日前〜▢日前、特定日以前」などをつかって、条件を指定できます。

日付の指定については、[サポートサイトのFAQ](https://support.repro.io/hc/ja/articles/23886462974489) に詳細な説明がありますので、こちらも参考にしてください。

### 既存ユーザー

Reproに登録されたすべてのユーザーが対象となります。既存ユーザーから特定条件を満たすユーザーを除外する場合は、 **and not** でフィルターを追加してください。

---

## プッシュ通知

* [APNs証明書の設定 (iOS)](https://docs.repro.io/ja/dev/sdk/push-notification/setup-ios.md)
  * [APP IDの作成](https://docs.repro.io/ja/dev/sdk/push-notification/setup-ios.md#app-id)
  * [証明書の作成](https://docs.repro.io/ja/dev/sdk/push-notification/setup-ios.md#create-certificate)
  * [Provisioning Profileの設定](https://docs.repro.io/ja/dev/sdk/push-notification/setup-ios.md#provisioning-profile)
* [FCMの設定 (Android)](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md)
  * [プロジェクトの作成](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md#id1)
  * [アプリの登録](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md#firebase-register-app)
  * [Firebase Cloud Messaging API（V1）を有効にする](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md#firebase-cloud-messaging-api-v1)
  * [Firebaseの秘密鍵を生成](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md#firebase)
  * [Firebaseの秘密鍵をReproに登録](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md#firebaserepro)
* [iOS](https://docs.repro.io/ja/dev/sdk/push-notification/ios.md)
  * [プッシュ通知の設定](https://docs.repro.io/ja/dev/sdk/push-notification/ios.md#id1)
  * [バッジを消す処理の実装](https://docs.repro.io/ja/dev/sdk/push-notification/ios.md#clear-badge)
  * [デバイストークンをReproに送信](https://docs.repro.io/ja/dev/sdk/push-notification/ios.md#repro)
  * [オプション：リッチ通知の受信準備](https://docs.repro.io/ja/dev/sdk/push-notification/ios.md#ios-receiving-rich-notification)
  * [オプション：ユニバーサルリンクを使用する](https://docs.repro.io/ja/dev/sdk/push-notification/ios.md#ios-universal-link-guide)
* [Android](https://docs.repro.io/ja/dev/sdk/push-notification/android.md)
  * [プッシュ通知の設定](https://docs.repro.io/ja/dev/sdk/push-notification/android.md#id1)
  * [Firebase SDKを導入する](https://docs.repro.io/ja/dev/sdk/push-notification/android.md#firebase-sdk)
  * [`AndroidManifest.xml` ファイルを編集する](https://docs.repro.io/ja/dev/sdk/push-notification/android.md#androidmanifest-xml)
  * [Registration IDをReproに送信](https://docs.repro.io/ja/dev/sdk/push-notification/android.md#registration-idrepro)
  * [オプション：プッシュ通知受信時の動作をカスタマイズする](https://docs.repro.io/ja/dev/sdk/push-notification/android.md#customize-receiver)
  * [オプション：アプリリンクを使用する](https://docs.repro.io/ja/dev/sdk/push-notification/android.md#android-app-link-guide)
* [Unity](https://docs.repro.io/ja/dev/sdk/push-notification/unity.md)
  * [プッシュ通知の設定](https://docs.repro.io/ja/dev/sdk/push-notification/unity.md#id1)
  * [Firebase Unity SDKを導入する](https://docs.repro.io/ja/dev/sdk/push-notification/unity.md#firebase-unity-sdk)
  * [iOSプラットフォーム](https://docs.repro.io/ja/dev/sdk/push-notification/unity.md#ios)
  * [Androidプラットフォーム](https://docs.repro.io/ja/dev/sdk/push-notification/unity.md#android)
  * [オプション：ユニバーサルリンク/アプリリンクを使用する](https://docs.repro.io/ja/dev/sdk/push-notification/unity.md#universal-link-guide-unity)
* [Cordova](https://docs.repro.io/ja/dev/sdk/push-notification/cordova.md)
  * [プッシュ通知の設定](https://docs.repro.io/ja/dev/sdk/push-notification/cordova.md#id1)
  * [`config.xml` ファイルを編集する](https://docs.repro.io/ja/dev/sdk/push-notification/cordova.md#config-xml)
  * [`google-services.json` ファイルを追加する](https://docs.repro.io/ja/dev/sdk/push-notification/cordova.md#google-services-json)
  * [Google Services Gradle Pluginを導入する](https://docs.repro.io/ja/dev/sdk/push-notification/cordova.md#google-services-gradle-plugin)
  * [オプション：Firebaseの依存バージョンを変更する](https://docs.repro.io/ja/dev/sdk/push-notification/cordova.md#firebase)
  * [デバイストークン、Registration IDをReproに送信](https://docs.repro.io/ja/dev/sdk/push-notification/cordova.md#registration-idrepro)
  * [オプション：ユニバーサルリンク/アプリリンクを使用する](https://docs.repro.io/ja/dev/sdk/push-notification/cordova.md#universal-link-guide-cordova)
* [Monaca](https://docs.repro.io/ja/dev/sdk/push-notification/monaca.md)
  * [プッシュ通知の設定](https://docs.repro.io/ja/dev/sdk/push-notification/monaca.md#id1)
  * [`config.xml` ファイルを編集する](https://docs.repro.io/ja/dev/sdk/push-notification/monaca.md#config-xml)
  * [`google-services.json` ファイルを追加する](https://docs.repro.io/ja/dev/sdk/push-notification/monaca.md#google-services-json)
  * [Google Services Gradle Pluginを導入する](https://docs.repro.io/ja/dev/sdk/push-notification/monaca.md#google-services-gradle-plugin)
  * [オプション：Firebaseの依存バージョンを変更する](https://docs.repro.io/ja/dev/sdk/push-notification/monaca.md#firebase)
  * [デバイストークン、Registration IDをReproに送信](https://docs.repro.io/ja/dev/sdk/push-notification/monaca.md#registration-idrepro)
  * [オプション：ユニバーサルリンク/アプリリンクを使用する](https://docs.repro.io/ja/dev/sdk/push-notification/monaca.md#id7)
* [Cocos2d-x](https://docs.repro.io/ja/dev/sdk/push-notification/cocos2d-x.md)
  * [プッシュ通知の設定](https://docs.repro.io/ja/dev/sdk/push-notification/cocos2d-x.md#id1)
  * [Firebase C++ SDKを導入する](https://docs.repro.io/ja/dev/sdk/push-notification/cocos2d-x.md#firebase-c-sdk)
  * [iOSプロジェクトの実装](https://docs.repro.io/ja/dev/sdk/push-notification/cocos2d-x.md#ios)
  * [Androidプロジェクトの実装](https://docs.repro.io/ja/dev/sdk/push-notification/cocos2d-x.md#android)
  * [オプション：ユニバーサルリンク/アプリリンクを使用する](https://docs.repro.io/ja/dev/sdk/push-notification/cocos2d-x.md#universal-link-guide-cocos2d-x)
* [React Native](https://docs.repro.io/ja/dev/sdk/push-notification/react-native.md)
  * [プッシュ通知の設定 (iOS)](https://docs.repro.io/ja/dev/sdk/push-notification/react-native.md#ios)
  * [プッシュ通知の設定 (Android)](https://docs.repro.io/ja/dev/sdk/push-notification/react-native.md#android)
  * [オプション：ユニバーサルリンク/アプリリンクを使用する](https://docs.repro.io/ja/dev/sdk/push-notification/react-native.md#universal-link-guide-react-native)
* [React Native (Expo)](https://docs.repro.io/ja/dev/sdk/push-notification/expo.md)
  * [FCMの設定 (Android)](https://docs.repro.io/ja/dev/sdk/push-notification/expo.md#fcm-android)
  * [APNs証明書の設定 (iOS)](https://docs.repro.io/ja/dev/sdk/push-notification/expo.md#apns-ios)
  * [React Native Firebase をインストールする (Android)](https://docs.repro.io/ja/dev/sdk/push-notification/expo.md#react-native-firebase-android)
  * [React Native Firebase の設定 (iOSプロジェクトを含む場合)](https://docs.repro.io/ja/dev/sdk/push-notification/expo.md#react-native-firebase-ios)
  * [チャネルの設定を追加する (Android)](https://docs.repro.io/ja/dev/sdk/push-notification/expo.md#android)
  * [google-services.json ファイルを配置する (Android)](https://docs.repro.io/ja/dev/sdk/push-notification/expo.md#google-services-json-android)
  * [Expo Notifications をインストールする (iOS/Android)](https://docs.repro.io/ja/dev/sdk/push-notification/expo.md#expo-notifications-ios-android)
  * [Entitlementsの設定を行う (iOS)](https://docs.repro.io/ja/dev/sdk/push-notification/expo.md#entitlements-ios)
  * [プッシュトークンをReproに送信する処理を実装する (iOS/Android)](https://docs.repro.io/ja/dev/sdk/push-notification/expo.md#repro-ios-android)
  * [アプリケーションのネイティブコードを生成する (iOS/Android)](https://docs.repro.io/ja/dev/sdk/push-notification/expo.md#ios-android)
* [Flutter](https://docs.repro.io/ja/dev/sdk/push-notification/flutter.md)
  * [プッシュ通知の設定(iOS)](https://docs.repro.io/ja/dev/sdk/push-notification/flutter.md#ios)
  * [プッシュ通知の設定(Android)](https://docs.repro.io/ja/dev/sdk/push-notification/flutter.md#android)
  * [オプション：ユニバーサルリンク/アプリリンクを使用する](https://docs.repro.io/ja/dev/sdk/push-notification/flutter.md#universal-link-guide-flutter)

---

js-cordova

## プッシュ通知 (Cordova / PhoneGap)

### プッシュ通知の設定

[APNs証明書の設定 (iOS)](https://docs.repro.io/ja/dev/sdk/push-notification/setup-ios.md) と [FCMの設定 (Android)](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md) を参照し、設定してください。



### `config.xml` ファイルを編集する

##### NOTE
* Cordova 7.1未満をご利用の場合は設定方法が異なります。詳細は [Cordova 7.1未満を利用する場合の設定](https://docs.repro.io/ja/dev/sdk/push-notification/cordova-old-version.md#cordova-old-cli) を参照してください。

#### 名前空間および `platform` タグを追加する

プロジェクト直下のconfig.xmlを開き、 `widget` タグに `xmlns:android="http://schemas.android.com/apk/res/android"` を追加してください。また、config.xmlの中に `<platform name="android">` タグが存在しない場合、 `widget` タグの下に追加してください。

```xml
<widget xmlns="http://www.w3.org/ns/widgets"
        xmlns:android="http://schemas.android.com/apk/res/android"
        id="..." version="1.0.0">
    ...
    <platform name="android">
        ...
    </platform>
```

#### config-fileタグを追加する

以下の手順で `config-file` タグを追加してください。

##### Receiverの登録

以下のXML中の "YOUR_PACKAGE_NAME" をアプリケーションのパッケージ名に置き換え、config.xmlの `<platform name="android">` タグの中に追加してください。

```xml
<config-file target="AndroidManifest.xml" parent="./application">
    <receiver
        android:name="io.repro.android.ReproReceiver"
        android:exported="true"
        android:permission="com.google.android.c2dm.permission.SEND">
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <category android:name="YOUR_PACKAGE_NAME" />
        </intent-filter>
    </receiver>
</config-file>
```

##### 通知チャンネルの設定

Android Oにて、ユーザーが通知を管理できるように通知チャンネルが導入されました。

Repro SDKで利用する通知チャンネルの設定を行うには、「ID」「名前」「ユーザー向けの説明」「badgeの表示有無」を以下のようにconfig.xmlの `<platform name="android">` タグの中に追加してください。IDと名前の指定は必須、その他は省略可能です。「ユーザー向けの説明」省略時は空文字列、「badgeの表示有無」省略時はbadgeの表示有りとなります。

##### WARNING
- アプリのtargetSDKVersionが26以上かつAndroid O以降の機種で動作させる場合、IDと名前が指定されていなければSDKはReproからのプッシュ通知を表示いたしませんのでご注意ください。

```xml
<config-file target="AndroidManifest.xml" parent="./application">
    <meta-data
        android:name="io.repro.android.PushNotification.ChannelId"
        android:value="YOUR_CHANNEL_ID">
    </meta-data>

    <meta-data
        android:name="io.repro.android.PushNotification.ChannelName"
        android:resource="@string/channel_name">
    </meta-data>

    <meta-data
        android:name="io.repro.android.PushNotification.ChannelDescription"
        android:resource="@string/channel_description">
    </meta-data>

    <meta-data
        android:name="io.repro.android.PushNotification.ShowBadge"
        android:value="true">
    </meta-data>
</config-file>
```

指定されたIDの通知チャンネルが存在しない場合は上記の指定を基にSDKが自動で作成し、指定されたIDの通知チャンネルが存在する場合は既存のものを利用します。

既存のものを利用する場合、SDKは「名前」、「ユーザー向けの説明」及び「チャンネルの重要度」を更新します。

また、アプリのtargetSDKVersionが25以下の場合、あるいは、Android O未満の機種の場合は、SDKは上記の通知チャンネルに関する設定を無視します。

##### NOTE
通知チャンネルはAndroid Oで導入されたAndroidの標準機能です。通知チャンネルの詳細は [こちら](https://developer.android.com/preview/features/notification-channels.html?hl=ja) をご覧ください。

##### 文字列リソースの追加

通知チャンネルの設定に合わせて、 `channel_name` と `channel_description` の文字列リソースを追加します。以下のようにconfig.xmlの `<platform name="android">` タグの中に追加してください。

```xml
<config-file target="res/values/strings.xml" parent="/*">
    <string name="channel_name">YOUR_CHANNEL_NAME</string>
    <string name="channel_description">YOUR_CHANNEL_DESCRIPTION</string>
</config-file>
```

##### アイコンと背景色のカスタマイズ

Android5.0以降の機種で、通知エリアに表示されるアイコンとその背景色をカスタマイズする場合は、以下のXMLをconfig.xmlの `<platform name="android">` タグの中に追加してください。Android5.0未満の機種では以下の設定は無視され、通知エリアにはアプリケーションのアイコンおよびシステムデフォルトの背景色が使用されます。

```xml
<config-file target="AndroidManifest.xml" parent="./application">
    <meta-data
        android:name="io.repro.android.PushNotification.SmallIcon"
        android:resource="@drawable/YOUR_ICON_ID">
    </meta-data>

    <meta-data
        android:name="io.repro.android.PushNotification.AccentColor"
        android:resource="@color/YOUR_COLOR_ID">
    </meta-data>
</config-file>
```



### `google-services.json` ファイルを追加する

[FCMの設定 (Android)](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md) でダウンロードした `google-services.json` をプロジェクトのディレクトリにコピーし、
下記のXMLをconfig.xmlの `<platform name="android">` タグの中に追加してください。

```xml
<resource-file src="google-services.json" target="app/google-services.json" />
```

##### NOTE
* Androidアプリをビルドした際に以下のようなWarningが表示される場合がありますが、SDKの動作に支障はありません。
  * `Warning: The app gradle file must have a dependency on com.google.firebase:firebase-core for Firebase services to work as intended.`
* Cordova Android 7.0未満をご利用の場合は設定方法が異なります。詳細は [Cordova Android 7.0未満を利用する場合の設定](https://docs.repro.io/ja/dev/sdk/push-notification/cordova-old-version.md#cordova-old-android) を参照してください。



### Google Services Gradle Pluginを導入する

Google Services Gradle Pluginを導入します。

`config.xml` 内の `<platform name="android">` タグの中に、以下の記述を追加してください。

```xml
<preference name="GradlePluginGoogleServicesEnabled" value="true" />
<preference name="GradlePluginGoogleServicesVersion" value="4.3.15" />
```

##### NOTE
* Cordova Plugin 6.8.0未満の場合はReproによって自動的にGoogle Services Gradle Plugin導入されるため、この設定は不要です。

##### WARNING
* この手順によるGoogle Services Gradle Pluginの導入はCordova Android 9.0.0以降の場合のみ可能です。
* Cordova Plugin 6.8.0以上を利用している かつ Cordova Android 9.0.0未満を利用している場合は、別途Google Services Gradle Pluginの導入を行う必要があります。



### オプション：Firebaseの依存バージョンを変更する

`firebase-core` 及び `firebase-messaging` の依存バージョンを変更する場合は、引数でバージョン指定した上でインストールしてください。例えば、 `firebase-core` のバージョン16.0.0、 `firebase-messaging` のバージョン17.1.0を指定する場合は、下記のコマンドを実行してください。

```sh
# cordova
$ cordova plugin add cordova-plugin-repro \
    --variable FIREBASE_CORE_VERSION=16.0.0 \
    --variable FIREBASE_MESSAGING_VERSION=17.1.0
```

##### WARNING
* [cordova-plugin-repro 6.5.0](https://docs.repro.io/ja/releases/sdk/cordova/releases.md#cordova-6-5-0) から、 `firebase-core` への依存は削除されました。これに伴い、 `FIREBASE_CORE_VERSION` の指定は不要となりました。

##### NOTE
* `FIREBASE_MESSAGING_VERSION` は17.1.0以上を指定してください。
* Cordova 7.1未満をご利用する場合、 `platforms/android/project.properties` を開き、以下のように修正してください。
  `platforms/android/project.properties` に対する修正はCordova CLIの操作により戻される場合があるため、
  ビルドする際は常にその内容をもう一度ご確認ください。
  * `com.google.firebase:firebase-core:$FIREBASE_CORE_VERSION` となっている箇所を
    `com.google.firebase:firebase-core:16.0.4` に修正
  * `com.google.firebase:firebase-messaging:$FIREBASE_MESSAGING_VERSION` となっている箇所を
    `com.google.firebase:firebase-messaging:17.3.4` に修正



### デバイストークン、Registration IDをReproに送信

プッシュ通知を利用するために、デバイストークン、Registration IDをReproに送信します。

index.jsにてプッシュ通知の設定を行います。

```js-cordova
   // phonegap-plugin-push instance variable
   var pushNotification;

   var app = {

     ...

     onDeviceReady: function() {
       app.receivedEvent('deviceready');

       Repro.setup("YOUR_APP_TOKEN");

       // For iOS
       Repro.enablePushNotificationForIOS();

       // For Android
       Repro.enablePushNotificationForAndroid();
     }
   };
```

上記の実装が終わったら、 [プッシュ通知作成画面](https://docs.repro.io/ja/dashboard/campaign/push-notification.md#push-create-message) をご覧ください。

#### プッシュ通知受信時の動作をカスタマイズする

プッシュ通知受信時の動作をカスタマイズするには、Repro Android SDKと同様の手順でサービスの実装を行う必要があります。
(JavaまたはKotlinにて `FirebaseMessagingService` を継承したクラスを実装する必要があります。)

詳細は [オプション：プッシュ通知受信時の動作をカスタマイズする](android.html#customize-receiver) を参照してください。



### オプション：ユニバーサルリンク/アプリリンクを使用する



端末に表示されたプッシュ通知およびアプリ内メッセージに設定されたリンクをタップした際に実行されるURLには、ユニバーサルリンク（またはアプリリンクと呼ばれる）を指定することが可能です。
（簡単のため、以下ではこれらをユニバーサルリンクと呼びます）

アプリにてユニバーサルリンクの実行時の処理を追加するには、以下の通り実装を行う必要があります。
（ここで設定された動作は、プッシュ通知およびアプリ内メッセージ対し有効となります。）

#### ユニバーサルリンクのURLパターンを登録する

ユニバーサルリンクを利用するためには、まずユニバーサルリンクのURLのパターン（正規表現）を指定する必要があります。

##### NOTE
パターン（正規表現）に合致すると、プッシュ通知の開封時や、アプリ内メッセージの遷移先に設定されたURLに対して、後述のコールバック処理をキックします。

また、アプリ内メッセージでHTMLコンテンツを表示するとき、そのコンテンツ内で発生したリクエストに対してもユニバーサルリンクの判定が行われます。

この指定は、iOSの場合は `AppDelegate` または `.plist` ファイル、Androidの場合は `Application` 継承クラス または `AndroidManifest.xml` ファイルのどちらか一方に記述することで行うことができます。

```objc
// AppDelegate.m

#import <Repro/Repro.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [Repro addOpenUrlFilterRegEx:@"https://example\\.com/page/"];
    [Repro addOpenUrlFilterRegEx:@"your-domain\\.com/.+\?universal=true"];
    ...
}


// .plist file
/*
<dict>
    <key>RPROpenUrlFilterRegExList</key>
    <array>
        <string>https://example\.com/page/</string>
        <string>your-domain\.com/.+\?universal=true</string>
    </array>
    ...
</dict>
*/
```

```java
// MyApplication.java

import io.repro.android.Repro;

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        Repro.addOpenUrlFilterRegEx("https://example\\.com/page/");
        Repro.addOpenUrlFilterRegEx("your-domain\\.com/.+\\?universal=true");
        ...
    }
...
}


// AndroidManifest.xml
// To specify multiple URL patterns, enter them separated by commas.
<application>
    ...
    <meta-data
        android:name="io.repro.android.OpenUrlFilterRegExList"
        android:value="https://example\\.com/page/;your-domain\\.com/.+\\?universal=true">
    </meta-data>
</application>
```

```kotlin
// MyApplication.kt

import io.repro.android.Repro

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        Repro.addOpenUrlFilterRegEx("https://example\\.com/page/")
        Repro.addOpenUrlFilterRegEx("your-domain\\.com/.+\\?universal=true")
        ...
    }
    ...
}


// AndroidManifest.xml
// To specify multiple URL patterns, enter them separated by commas.
<application>
    ...
    <meta-data
        android:name="io.repro.android.OpenUrlFilterRegExList"
        android:value="https://example\\.com/page/;your-domain\\.com/.+\\?universal=true">
    </meta-data>
</application>
```

```swift
// AppDelegate.swift

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
{
    Repro.add(openUrlFilterRegEx: "https://example\\.com/page/")
    Repro.add(openUrlFilterRegEx: "your-domain\\.com/.+\\?universal=true")
    ...
}

// .plist file
/*
<dict>
    <key>RPROpenUrlFilterRegExList</key>
    <array>
        <string>https://example\.com/page/</string>
        <string>your-domain\.com/.+\?universal=true</string>
    </array>
    ...
</dict>
*/
```

```dart
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

```csharp
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

```cpp
// YourAppNameScene.cpp

bool YourAppName::init() {
    ReproCpp::addOpenUrlFilterRegEx("https://example\\.com/page/");
    ReproCpp::addOpenUrlFilterRegEx("your-domain\\.com/.+\\?universal=true");
    ...
}
```

```js-cordova
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

```js-react-native
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

##### WARNING
ユニバーサルリンクとして設定するURLパターンは、可能な限り **ドメインとパスまで含めて具体的に指定** し、 **全て小文字で指定** してください。

もし、 https のようにスキームのみを指定した場合、アプリ内メッセージで表示された画面内で実行されたスクリプトなどによるリクエストもユニバーサルリンクと誤って判定され、意図しないタイミングでコールバック処理が実行される可能性があります。

また、URLパターンのスキーム/ドメイン部分に大文字を使用した場合、HTMLアプリ内メッセージで表示したボタンからユニバーサルリンクを使って遷移させようとするときに、スキーム/ドメイン部分が自動的に小文字に変換されて処理されます。パターン（正規表現）に一致せず、意図したタイミングでコールバック処理が実行されない可能性があります。

#### ユニバーサルリンク実行時の処理を登録する

次に、ユニバーサルリンクが実行された際に動作するコールバック処理を実装します。
処理内には、例えばURLのパターンに応じて画面遷移を行う動作などを記述します。

```objc
#import <Repro/Repro.h>

...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [Repro setOpenUrlCallback:^(NSURL *url) {
        if ([url.host isEqualToString:@"example.com"]) {
            // In case of your universal link perform navigation, present content, ...
            handleUniversalLink(url);
        }
    }];

    ...
    [Repro setup:@"YOUR_APP_TOKEN"];
    ...
}
```

```swift
// Set a callback that is executed everytime an URL is about to be opened
Repro.setOpenUrlCallback { url in
    if url.host == "example.com" {
        // In case of your universal link perform navigation, present content, ...
        handleUniversalLink(url)
    }
}
...
Repro.setup(token: "YOUR_APP_TOKEN")
...
```

```java
import io.repro.android.Repro;

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        // In order to execute a callback when a push notification is tapped,
        // the callback must be set in Application, not Activity.
        Repro.setOpenUrlCallback(new Repro.OpenUrlCallback() {
            // ** This callback method is executed in the main thread **
            @Override
            public void onOpened(Uri uri) {
                if ("example.com".equals(uri.getHost())) {
                    // In case of your universal link perform navigation, present content, ...
                }
            }
        });

        ...
        Repro.setup(this, YOUR_APP_TOKEN);
        ...
    }
    ...
}
```

```kotlin
import io.repro.android.Repro

class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        // In order to execute a callback when a push notification is tapped,
        // the callback must be set in Application, not Activity.
        Repro.setOpenUrlCallback { uri ->
            // ** This callback method is executed in the main thread **
            if (uri.host == "example.com") {
                // In case of your universal link perform navigation, present content, ...
            }
        }

        ...
        Repro.setup(this, "YOUR_APP_TOKEN")
        ...
    }
    ...
}
```

```dart
Repro.setOpenUrlCallback((uri) { // uri is of type Uri
   debugPrint("Universal Link Callback Handler received: " + uri.toString());
});
```

```csharp
// Somewhere before Repro.Setup(...)
Repro.SetOpenUrlCallback(uri => // uri is of type Uri
{
    Debug.Log("Universal Link Callback Handler received: " + uri.ToString());
});
```

```cpp
bool YourAppName::init() {
    ReproCpp::addOpenUrlFilterRegEx(...);

    ReproCpp::setOpenUrlCallback([](const char *url) {
        if (strcmp(url, "example.com") == 0) {
            // In case of your universal link perform navigation, present content, ...
        }
    });

    ReproCpp::setup("YOUR_APP_TOKEN")
    ...
}
```

```js-cordova
Repro.setOpenUrlCallback(function(url) { // url is of type String
    alert('Universal Link Callback Handler received: ' + url);
    if (url.includes("http://example.org")) {
        // In case of your universal link perform navigation, present content, ...
    }
});
```

```js-react-native
Repro.setOpenUrlCallback( (url) => {  // url is of type String
    console.log('Universal Link Callback Handler received: ' + url);
    if (url.includes("http://example.org")) {
        // In case of your universal link perform navigation, present content, ...
    }
});
```

---

## 特定のバージョンにおけるCordovaでの対応方法



### Cordova 7.1未満を利用する場合の設定

#### 名前空間および `platform` タグを追加する

プロジェクト直下のconfig.xmlを開き、 `widget` タグに `xmlns:android="http://schemas.android.com/apk/res/android"` を追加してください。また、config.xmlの中に `<platform name="android">` タグが存在しない場合、 `widget` タグの下に追加してください。

```xml
<widget xmlns="http://www.w3.org/ns/widgets"
        xmlns:android="http://schemas.android.com/apk/res/android"
        id="..." version="1.0.0">
    ...
    <platform name="android">
        ...
    </platform>
```

#### custom-config-fileタグを追加する

Cordova 7.1未満をご利用する場合、config-fileタグが動作しないため、以下の手順で `config.xml` を編集してください：

* cordova-custom-configを導入
  ```shell
  $ cordova plugin add cordova-custom-config
  ```
* [config-fileタグを追加する](cordova.html#config-file) にて設定したXMLを一つの `custom-config-file` タグの中に記述し、さらにその `custom-config-file` タグを `<platform name="android">` タグの中に追加してください
  * "YOUR_PACKAGE_NAME" をアプリケーションのパッケージ名に置き換えてください

  ```xml
  <custom-config-file parent="./application" target="AndroidManifest.xml">
      <!-- Receiver -->
      <receiver
          android:name="io.repro.android.ReproReceiver"
          android:exported="true"
          android:permission="com.google.android.c2dm.permission.SEND">
          <intent-filter>
              <action android:name="com.google.android.c2dm.intent.RECEIVE" />
              <category android:name="YOUR_PACKAGE_NAME" />
          </intent-filter>
      </receiver>

      <!-- Notification Channel -->
      <meta-data
          android:name="io.repro.android.PushNotification.ChannelId"
          android:value="YOUR_CHANNEL_ID">
      </meta-data>
      <meta-data
          android:name="io.repro.android.PushNotification.ChannelName"
          android:resource="@string/channel_name">
      </meta-data>
      <meta-data
          android:name="io.repro.android.PushNotification.ChannelDescription"
          android:resource="@string/channel_description">
      </meta-data>
      <meta-data
          android:name="io.repro.android.PushNotification.ShowBadge"
          android:value="true">
      </meta-data>

      <!-- Icon and Accent Color -->
      <meta-data
          android:name="io.repro.android.PushNotification.SmallIcon"
          android:resource="@drawable/YOUR_ICON_ID">
      </meta-data>

      <meta-data
          android:name="io.repro.android.PushNotification.AccentColor"
          android:resource="@color/YOUR_COLOR_ID">
      </meta-data>
  </custom-config-file>
  ```
* プロジェクト直下で下記の内容で `ReproStrings.xml` というファイルを作成してください：
  ```xml
  
  <resources>
      <string name="channel_name">YOUR_CHANNEL_NAME</string>
      <string name="channel_description">YOUR_CHANNEL_DESCRIPTION</string>
  </resources>
  ```
* config.xmlの `<platform name="android">` タグの中に下記の設定を追加してください：
  ```xml
  <resource-file src="ReproStrings.xml" target="res/values/ReproStrings.xml" />
  ```



### Cordova Android 7.0未満を利用する場合の設定

#### `google-services.json` ファイルを追加する

[FCMの設定 (Android)](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md) でダウンロードした `google-services.json` をプロジェクトのディレクトリにコピーし、
下記のXMLをconfig.xmlの `<platform name="android">` タグの中に追加してください。

```xml
<resource-file src="google-services.json" target="google-services.json" />
```

---

## Cordova Plugin リリースノート

* [Cordova Plugin 更新手順](https://docs.repro.io/ja/releases/sdk/cordova/upgrade.md)



### 6.27.1 (2026/07/01)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.24.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-24-1)
  - [Android SDK 5.24.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-24-0)



### 6.27.0 (2026/04/01)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [Android SDK 5.22.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-22-0)



### 6.26.0 (2026/03/05)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.23.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-23-0)
  - [Android SDK 5.21.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-21-0)



### 6.25.1 (2026/01/27)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.22.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-22-1)
  - [Android SDK 5.20.7](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-20-7)

### 6.25.0 (2025/12/15)

修正

- [cordova-ios@8.0.0](https://cordova.apache.org/announcements/2025/11/23/cordova-ios-8.0.0.html) の影響によってiOSアプリのビルドに失敗する問題を修正しました。

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.22.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-22-0)



### 6.24.4 (2025/11/19)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [Android SDK 5.20.4](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-20-4)



### 6.24.3 (2025/11/14)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.21.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-21-1)
  - [Android SDK 5.20.3](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-20-3)



### 6.24.2 (2025/10/23)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [Android SDK 5.20.2](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-20-2)



### 6.24.1 (2025/09/29)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [Android SDK 5.20.1](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-20-1)



### 6.24.0 (2025/07/28)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.21.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-21-0)
  - [Android SDK 5.20.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-20-0)



### 6.23.0 (2025/04/25)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.20.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-20-0)
  - [Android SDK 5.19.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-19-0)



### 6.22.0 (2024/12/26)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.19.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-19-0)
  - [Android SDK 5.18.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-18-0)



### 6.21.0 (2024/10/30)

変更

- UXオプティマイザー機能（β）に関するAPIを追加しました。
  - 詳細は [こちら](https://docs.repro.io/ja/dev/sdk/remote-config.md) をご覧ください。
- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [Android SDK 5.17.1](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-17-1)



### 6.20.0 (2024/10/03)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.18.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-18-0)
  - [Android SDK 5.17.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-17-0)



### 6.19.0 (2024/07/11)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.17.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-17-0)
  - [Android SDK 5.16.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-16-0)



### 6.18.0 (2024/05/17)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.16.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-16-0)
  - [Android SDK 5.15.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-15-0)



### 6.17.0 (2024/04/30)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.15.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-15-0)
  - [Android SDK 5.14.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-14-0)



### 6.16.0 (2024/01/19)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.14.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-14-0)
  - [Android SDK 5.13.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-13-0)



### 6.15.1 (2023/12/22)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.13.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-13-1)



### 6.15.0 (2023/11/17)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.13.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-13-0)
  - [Android SDK 5.12.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-12-0)



### 6.14.0 (2023/10/16)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.12.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-12-0)
  - [Android SDK 5.11.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-11-0)



### 6.13.0 (2023/09/12)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.11.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-11-1)
  - [Android SDK 5.10.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-10-0)



### 6.12.0 (2023/06/13)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.11.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-11-0)
  - [Android SDK 5.9.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-9-0)



### 6.11.0 (2023/03/08)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.9.5](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-9-5)
  - [Android SDK 5.8.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-8-0)



### 6.10.4 (2023/02/14)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.9.4](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-9-4)



### 6.10.3 (2023/01/25)

修正

- 最新のバージョンのAndroid Gradle Pluginの影響によってAndroidアプリのビルドに失敗する問題を修正しました。



### 6.10.2 (2022/12/28)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.9.3](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-9-3)
  - [Android SDK 5.7.2](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-7-2)



### 6.10.1 (2022/10/05)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.9.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-9-1)
  - [Android SDK 5.7.1](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-7-1)



### 6.10.0 (2022/08/31)

新機能

- ユニバーサルリンク･アプリリンクに対応するためのコールバック処理の記述が可能になりました。
  - 詳細は [こちら](https://docs.repro.io/ja/dev/sdk/push-notification/cordova.md#universal-link-guide-cordova) をご覧ください。

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.9.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-9-0)
  - [Android SDK 5.7.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-7-0)



### 6.9.0 (2022/04/14)

変更

- サポート品質の向上のため、クロスプラットフォーム環境におけるSDKの情報を取得する機能を追加しました。
- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.8.3](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-8-3)
  - [Android SDK 5.6.3](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-6-3)



### 6.8.0 (2022/03/22)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.8.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-8-1)
  - [Android SDK 5.6.2](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-6-2)
- Cordova Android 10以上の使用時にSDKを導入するとビルドエラーが発生する問題を修正しました。
  - この対応と関連して、SDKが自動的にGoogle Services Gradle Pluginを設定しないように変更されました。今後は開発時にアプリ側でプラグインを導入する必要があります。
  - 詳細は [Google Services Gradle Pluginを導入する](https://docs.repro.io/ja/dev/sdk/push-notification/cordova.md#cordova-google-plugin) を参照してください。



### 6.7.0  (2021/12/07)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.8.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-8-0)
  - [Android SDK 5.6.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-6-0)
- NewsFeed機能として以下のインターフェースを追加しました。詳細は [開発ガイド](https://docs.repro.io/ja/dev/sdk/newsfeed.md) を参照してください。
  - `getNewsFeedsWithLimitAndCampaignType`
  - `getNewsFeedsWithLimitAndOffsetIdAndCampaignType`



### 6.6.0  (2021/10/26)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.7.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-7-1)



### 6.5.0  (2021/08/13)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.6.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-6-0)
  - [Android SDK 5.5.1](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-5-1)
- firebase-core への依存を削除しました。
  - Androidアプリをビルドした際に以下のようなWarningが表示される場合がありますが、SDKの動作に支障はありません。
    - `Warning: The app gradle file must have a dependency on com.google.firebase:firebase-core for Firebase services to work as intended.`



### 6.4.0  (2021/06/04)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.5.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-5-1)
  - [Android SDK 5.4.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-4-0)



### 6.3.0  (2021/03/09)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.4.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-4-0)
  - [Android SDK 5.3.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-3-0)



### 6.2.0  (2021/02/02)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.3.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-3-0)
  - [Android SDK 5.2.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-2-0)



### 6.1.1  (2020/12/23)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.2.12](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-2-12)
  - [Android SDK 5.1.9](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-1-9)



### 6.1.0  (2020/11/03)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.2.2](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-2-2)
  - [Android SDK 5.1.3](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-1-3)



### 6.0.0  (2020/08/25)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.1.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-1-0)
  - [Android SDK 5.1.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-1-0)
- ニュースフィード機能およびAIレコメンド・アプリ内メッセージ連携機能（クローズドβ）に関するAPIを追加しました。
  - ニュースフィード機能についての詳細は [こちら](https://docs.repro.io/ja/dev/sdk/newsfeed.md) をご覧ください。



### 5.1.0  (2020/07/06)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 4.7.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-4-7-1)
  - [Android SDK 4.4.1](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-4-4-1)



### 5.0.0  (2019/12/20)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 4.5.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-4-5-0)
  - [Android SDK 4.3.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-4-3-0)
- 動画機能に関する以下のAPIを削除しました。
  - `startRecording`
  - `stopRecording`
  - `pauseRecording`
  - `resumeRecording`
  - `maskWithRect`
  - `maskFullScreen`
  - `unmask`



### 4.4.1  (2019/11/19)

修正

- 2019/11/19現在、最新のバージョンのAndroid Gradle pluginの影響によってAndroidアプリのビルドに失敗する問題を修正しました。



### 4.4.0  (2019/04/05)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 3.3.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-3-3-0)
- オプトアウト機能用のAPIを追加しました。
  - 詳細は [こちら](https://docs.repro.io/ja/dev/sdk/optout/index.md) をご覧ください。



### 4.3.0 (2019/02/15)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 3.2.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-3-2-0)
  - [Android SDK 3.3.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-3-3-0)
- 動画機能に関する主要なコードを削除し、動画機能が動作しないようにしました。以下のAPIを呼び出しても問題ありませんが何も実行されません。
  - `startRecording`
  - `stopRecording`
  - `pauseRecording`
  - `resumeRecording`
  - `maskWithRect`
  - `unmask`

  #### WARNING
  録画関連APIは削除されました。2019年5月22日現在、これを利用することはできません。



### 4.2.0 (2018/11/14)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 3.0.4](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-3-0-4)
  - [Android SDK 3.1.1](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-3-1-1)
- GCMのサポートを廃止しました。
  - GCMをご利用中の場合はFCMへの移行が必要となります。移行手順は [FCMへの移行手順: Cordova](https://docs.repro.io/ja/releases/migration-to-fcm/cordova.md) をご覧ください。
- プッシュ通知をご利用いただくには、firebase-messaging バージョン17.1.0以降が必須となりました。
  - 現在 firebase-messaging バージョン17.1.0未満をご利用中の場合は、17.1.0以降に変更してください。
  - また、プッシュ通知の実装で `Repro.enablePushNotificationForAndroid()` の呼び出しが必須となりました。詳細は [プッシュ通知 (Cordova / PhoneGap)](https://docs.repro.io/ja/dev/sdk/push-notification/cordova.md) をご覧ください。



### 4.1.0 (2018/09/25)

変更

- Cordova CLI 6.5未満のバージョンをサポート対象から除外しました。
- iOSにてプッシュ通知をご利用する際にphonegap-plugin-pushを導入する必要がなくなりました。
  - 新規にiOS上でプッシュ通知をセットアップするためのメソッドをを追加しました。詳細は [こちら](https://docs.repro.io/ja/dev/sdk/push-notification/cordova.md#cordova-enable-push-notification-for-ios) をご覧ください。
  - Capabilitiesの設定は自動で行われるようになりました。



### 4.0.0 (2018/08/27)

SDKを更新しました。

- [iOS SDK 3.0.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-3-0-0)
- [Android SDK 3.0.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-3-0-0)

データアップロードの処理を変更しました。

- Cordova Plugin 4.0.0未満は、2019年6月24日以降にセッションデータをアップロードできなくなります。
- そのため、2019年6月24日までにCordova Plugin 4.0.0以上にアップデートしてください。



### 3.7.0 (2018/07/24)

SDKを更新しました。

- [iOS SDK 2.12.2](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-2-12-2)
- [Android SDK 2.12.6](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-2-12-6)

iOSプラットフォームのdeployment targetを6.0から8.0に変更しました。詳細はiOS SDK 2.12.2の [リリースノート](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-2-12-2) をご覧ください。



### 3.6.2 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。

Cordova Pluginに同梱されているiOS SDKおよびAndroid SDKのバージョン

- [iOS SDK 2.6.10](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-2-6-10)
- [Android SDK 2.7.11](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-2-7-11)



### 3.6.1 (2017/10/18)

SDKを更新しました。

- [iOS SDK 2.6.9](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-2-6-9)
- [Android SDK 2.7.10](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-2-7-10)



### 3.6.0 (2017/07/12)

SDKを更新しました。

- [iOS SDK 2.5.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-2-5-0)
- [Android SDK 2.6.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-2-6-0)



### 3.1.3 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。

Cordova Pluginに同梱されているiOS SDKおよびAndroid SDKのバージョン

- [iOS SDK 2.1.13](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-2-1-13)
- [Android SDK 2.1.23](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-2-1-23)



### 3.1.2

SDKを更新しました。

- [iOS SDK 2.1.12](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-2-1-12)
- [Android SDK 2.1.11](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-2-1-11)

### 3.1.1

SDKを更新しました。

- iOS SDK: 2.1.3
- Android SDK: 2.1.2

### 3.1.0

SDKを更新しました。

- iOS SDK: 2.1.0
- Android SDK: 2.1.0



### 3.0.3 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。

Cordova Pluginに同梱されているiOS SDKおよびAndroid SDKのバージョン

- [iOS SDK 2.0.10](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-2-0-10)
- [Android SDK 2.0.5](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-2-0-5)

### 3.0.2

SDKを更新しました。

- iOS SDK: 2.0.9

### 3.0.1

SDKを更新しました。

- iOS SDK: 2.0.6

### 3.0.0

SDKを更新しました。

- iOS SDK: 2.0.0
- Android SDK: 2.0.0



### 2.3.2 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。

Cordova Pluginに同梱されているiOS SDKおよびAndroid SDKのバージョン

- [iOS SDK 1.7.35](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-1-7-35)
- [Android SDK 1.2.10](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-1-2-10)

### 2.3.1

SDKを更新しました。

- iOS SDK: 1.7.34
- Android SDK: 1.2.9

### 2.3.0

SDKを更新しました。

- Android SDK: 1.2.0



### 2.2.1 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。

Cordova Pluginに同梱されているiOS SDKおよびAndroid SDKのバージョン

- [iOS SDK 1.7.35](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-1-7-35)
- [Android SDK 1.1.48](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-1-1-48)

### 2.2.0

SDKを更新しました。

- iOS SDK: 1.7.30
- Android SDK: 1.1.47

### 2.1.0

SDKを更新しました。

- iOS SDK: 1.7.3
- Android SDK: 1.1.2



### 2.0.2 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。

Cordova Pluginに同梱されているiOS SDKおよびAndroid SDKのバージョン

- [iOS SDK 1.5.2](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-1-5-2)
- [Android SDK 0.14.6](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-0-14-6)

### 2.0.1

Cordova 5.2 をサポートしました。

SDKを更新しました。

- iOS SDK: 1.5.1
- Android SDK: 0.14.5

### 2.0.0

Androidをサポートしました。

SDKを更新しました。

- iOS SDK: 1.4.22
- Android SDK: 0.13.18

変更

- `maskWithRect` API の引数の順序を `maskWithRect(x, y, width, height, key)` から `maskWithRect(key, x, y, width, height)` に変更しました。

### 1.2.0

SDKを更新しました。

- iOS SDK: 1.4.0

### 1.1.2

SDKを更新しました。

- iOS SDK: 1.3.23

### 1.1.1

SDKを更新しました。

- iOS SDK: 1.2.10.1

### 1.1.0

SDKを更新しました。

- iOS SDK: 1.2.10

### 1.0.2

- pluginのpublish先をnpmに移行しました。

### 1.0.1

- pluginのIDを変更しました。

### 1.0.0

SDKを更新しました。

- iOS SDK: 1.0.5

### 0.0.14

- setPushDeviceToken API を追加しました。

### 0.0.13

SDKを更新しました。

- iOS SDK: 0.10.4.1

### 0.0.12

SDKを更新しました。

- iOS SDK: 0.9.11

### 0.0.11

SDKを更新しました。

- iOS SDK: 0.9.8

### 0.0.10

SDKを更新しました。

- iOS SDK: 0.9.7

### 0.0.9

SDKを更新しました。

- iOS SDK: 0.8.0

### 0.0.8

SDKを更新しました。

- iOS SDK: 0.4.6

### 0.0.7

SDKを更新しました。

- iOS SDK: 0.4.5

### 0.0.6

SDKを更新しました。

- iOS SDK: 0.4.4

### 0.0.5

SDKを更新しました。

- iOS SDK: 0.4.3

### 0.0.4

SDKを更新しました。

- iOS SDK: 0.4.2

### 0.0.3

SDKを更新しました。

- iOS SDK: 0.4.1

### 0.0.2

SDKを更新しました。

- iOS SDK: 0.4.0

### 0.0.1

SDKを更新しました。

- iOS SDK: 0.3.9

---

## Cordova Plugin 更新手順

下記のコマンドを実行してください。

```sh
cordova plugin rm cordova-plugin-repro
cordova plugin add cordova-plugin-repro
```

---

objc,swift

## iOS SDK リリースノート

* [iOS SDK 更新手順](https://docs.repro.io/ja/releases/sdk/ios/upgrade.md)
  * [Swift Package Manager](https://docs.repro.io/ja/releases/sdk/ios/upgrade.md#swift-package-manager)
  * [CocoaPods](https://docs.repro.io/ja/releases/sdk/ios/upgrade.md#cocoapods)
  * [SDKをダウンロードしてインストールする](https://docs.repro.io/ja/releases/sdk/ios/upgrade.md#sdk)



##### WARNING
- [iOS SDK 5.14.0](#ios-5-14-0) より、広告IDを取得するためには別途設定が必要になります。



### 5.24.1 (2026/07/01)

修正

- SDKの初期化時に稀にアプリがクラッシュする可能性がある問題を修正しました。



### 5.24.0 (2026/04/24)

変更

- 内部用のAPIを追加しました。



### 5.23.0 (2026/03/05)

新機能

- アプリ内メッセージを表示する際の表示優先度を設定できるようになりました。
  - 詳細は [アプリ内メッセージの表示優先度を調整する](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md#in-app-message-delivery) を参照してください。



### 5.22.1 (2026/01/27)

修正

- ユーザープロフィールのセットで発火するトリガーをセット操作のみに修正しました。詳細は [ユーザープロフィールのセットによってトリガーを実行する](https://docs.repro.io/ja/dashboard/campaign/in-app-message.html#id25) を参照してください。



### 5.22.0 (2025/12/15)

新機能

- HTMLアプリ内メッセージを表示するWkWebViewのURLが変更できるようになりました。デフォルトは `https://io.repro.repro` です。
  - 詳細は [App-Bound Domains を有効にしている場合（iOSのみ）](https://docs.repro.io/ja/dev/sdk/in-app-message.md#html-inapp-message-custom-base-url) を参照してください。



### 5.21.1 (2025/11/14)

修正

- 軽微な不具合を修正しました。



### 5.21.0 (2025/07/28)

新機能

- ユーザープロフィールの設定方法として、条件付きセット操作、増減操作、削除の操作が追加されました。
  - 詳細は [ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md) を参照してください。

変更

- WebViewでReproを利用するためのライブラリ `repro.js` のバージョン8がリリースされました。
  - 詳細は [Webページにトラッキングコードを追加する](/ja/dev/sdk/webview.html#web) を参照してください。



### 5.20.0 (2025/04/25)

修正

- 軽微な不具合を修正しました。



### 5.19.1 (2025/04/07)

変更

React NativeおよびFlutter向けプラグインの機能改善に向け、内部処理を修正しました。



### 5.19.0 (2024/12/26)

新機能

- HTMLアプリ内メッセージにおいて、オリジナルテンプレート(ID1000)でメッセージを作成する際、メッセージ内で任意のイベントのトラッキングやユーザープロフィールの設定を行うことができるようになりました。
  - 詳細は [HTMLアプリ内メッセージでイベントトラッキングおよびユーザープロフィールの設定を行う](https://docs.repro.io/ja/dashboard/campaign/html-in-app-message.md#html-inapp-tracking) 、 [ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md) および [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md) を参照してください
- HTMLアプリ内メッセージにおいて、オリジナルテンプレート(ID1000)でメッセージを作成する際、メッセージ内でアプリ内メッセージの表示トリガーとなったイベントのプロパティを取得できるようになりました。
  - 詳細は [HTMLアプリ内メッセージでイベントプロパティの取得を行う](https://docs.repro.io/ja/dashboard/campaign/html-in-app-message.md#html-inapp-triggered-properties) を参照してください。
- WebViewを利用してWebページを表示する際、ページ内でユーザープロフィールの設定を行うことができるようになりました。
  - 詳細は [WebView](https://docs.repro.io/ja/dev/sdk/webview.md) および [ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md) を参照してください。

変更

- WebViewでReproを利用するためのライブラリ `repro.js` のバージョン6がリリースされました。
  - 詳細は [Webページにトラッキングコードを追加する](/ja/dev/sdk/webview.html#web) を参照してください。

##### WARNING
- WebViewにおいてユーザープロフィールの設定を行う場合は、バージョン6の `repro.js` を利用する必要があります。



### 5.18.0 (2024/10/03)

修正

- データ収集における信頼性向上のための軽微な修正を行いました。



### 5.17.1 (2024/08/06)

修正

- QRコードを用いてオーディエンスにユーザーを登録する機能について、アプリの構成によって正しく機能しない問題を修正しました。

##### NOTE
アプリの構成で `AppDelegate` `SceneDelegate` を使用していない場合、このバージョンにアップデートしてご利用ください。



### 5.17.0 (2024/07/10)

新機能

- 「ニュースフィード」機能で取得できるパラメータに `linkUrlString` `imageUrlString` を追加しました。
  - パラメータの追加に伴い、 `linkUrl` `imageUrl` は非推奨になりました。
  - 詳細は [ニュースフィード](https://docs.repro.io/ja/dev/sdk/newsfeed.html)  を参照してください。



### 5.16.0 (2024/05/17)

新機能

- QRコードを用いてオーディエンスにユーザーを登録する機能を追加しました。
  - 詳細は [QRコードを用いてオーディエンスにユーザーを登録する](https://docs.repro.io/ja/dev/sdk/qr-code.md#qr-code) を参照してください。



### 5.15.0 (2024/04/30)

新機能

- 標準ユーザープロフィールとして登録可能な項目を追加しました。
  - 詳細は [標準ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md#standard-user-profile) を参照してください。



### 5.14.0 (2024/01/19)

変更

- 広告IDをデフォルトで取得しないよう変更しました。
  - 広告IDを取得する方法については [広告ID取得設定](https://docs.repro.io/ja/dev/sdk/ad-id.md#ad-id) を参照してください。

修正

- アプリ内メッセージの情報を受信した際、ごく稀にアプリケーションのクラッシュが発生する問題を修正しました。



### 5.13.1 (2023/12/22)

修正

- アプリ内メッセージを表示する際、ごく稀にアプリケーションのクラッシュが発生する問題を修正しました。



### 5.13.0 (2023/11/17)

新機能

- SDKが [Xcodeによるコード署名](https://developer.apple.com/support/code-signing/) に対応しました。
- SDKに [プライバシーマニフェスト](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_data_use_in_privacy_manifests?language=objc) (PrivacyInfo.xcprivacyファイル)が追加されました。
- また、 [プライバシーに影響を及ぼすAPIとしてが必要な宣言](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api?language=objc) をプライバシーマニフェストに追加しました。



### 5.12.0 (2023/10/16)

変更

- アプリ内メッセージにおいて、これを閉じたことを内部的に記録する条件を一部変更しました。
  - 例えばバナータイプのアプリ内メッセージが時間経過で自動的に消える場合など、ユーザーが意図してメッセージを閉じる操作を行わない場合は記録を行わないようになります。



### 5.11.1 (2023/09/12)

修正

- 特定の端末および実装において、バナータイプのアプリ内メッセージが不正な位置に表示される問題を修正しました。
- デバイスを回転させた際、HTMLアプリ内メッセージが意図しない表示となる場合がある問題を修正しました。



### 5.11.0 (2023/06/12)

変更

- SDKがサーバーと通信をする際のデータ量を削減する対応を行いました。



### 5.10.1 (2023/05/17)

修正

- HTMLアプリ内メッセージのディープリンクで画面遷移する場合に、アプリの実装によっては画面遷移に失敗する可能性がある不具合を修正しました。



### 5.10.0 (2023/04/04)

修正

- 画面の回転や特定のHTMLの機能の影響で、HTMLアプリ内メッセージが正しく全画面で表示されない場合がある問題を修正しました。
- アプリの起動時に表示されるアプリ内メッセージが、オリエンテーションマスクの設定を制限しているビューコントローラで正しく回転されない問題を修正しました。
- アプリ内メッセージの画像のキャッシュ処理を改善しました。

##### WARNING
HTMLアプリ内メッセージで開いたディープリンクの処理がapp delegateのkeyWindowプロパティに依存している場合に、画面遷移に失敗する可能性があります。
 
上記に該当する場合は、このバージョンのSDKを利用しないで下さい。
 



### 5.9.5 (2023/03/08)

修正

- ユニバーサルリンク機能におけるURLフィルターが設定されていない場合に、誤ったエラーメッセージが表示される問題を修正しました。



### 5.9.4 (2023/02/13)

修正

- ステータスバーが存在しないアプリにおいて、バナータイプのアプリ内メッセージがデバイスのノッチ部分に隠れる場合がある問題を修正しました。



### 5.9.3 (2022/12/27)

修正

- シルバーエッグレコメンドメッセージの利用時、サーバーに対し誤ったパラメータを送信している問題を修正しました。



### 5.9.2 (2022/10/17)

修正

- Unityを利用したアプリにおいて、一部の環境でRepro SDKの初期化時にアプリが停止する可能性がある問題を修正しました。



### 5.9.1 (2022/10/05)

変更

- 内部仕様の変更により、不要となった情報をサーバーに送信しないよう変更しました。



### 5.9.0 (2022/07/22)

新機能

- ユニバーサルリンク･アプリリンクに対応するためのコールバック処理の記述が可能になりました。
  - 詳細は [オプション：ユニバーサルリンクを使用する](https://docs.repro.io/ja/dev/sdk/push-notification/ios.md#ios-universal-link-guide) をご覧ください。



### 5.8.3 (2022/04/11)

修正

- Repro SDKのAPIに誤ったパラメータを指定した際の検知機能を強化しました。



### 5.8.2 (2022/03/25)

修正

- Repro SDKをXcode 13.3のSwift Package Managerでインストール出来ない問題を修正しました。



### 5.8.1 (2022/02/16)

修正

- ログレベルのデフォルト値が正しくない問題を修正しました。
  - [ログレベル](https://docs.repro.io/ja/dev/sdk/log.md) に掲載の通り、 `Info` レベルがデフォルトの動作となります。



### 5.8.0 (2021/12/06)

新機能

- 「ニュースフィード」機能を用いて、プッシュ通知に加え アプリ内メッセージおよび Webメッセージ の履歴を取得できるようになりました。
  - 詳細は [こちら](https://docs.repro.io/ja/dev/sdk/newsfeed.md) をご覧ください。



### 5.7.1 (2021/10/22)

修正

- アプリの実行中にユーザーIDをセットしない場合であっても、エクスポートされたイベントデータには直前に使用していたユーザーIDが出力される仕様となるよう変更をしました。



### 5.7.0 (2021/10/01)

新機能

- Swift Package Manager へ対応しました。
- Apple M1 環境へ対応しました。
  : - 上記にともないフレームワークの形式を embeddedframework から xcframework に変更しました。

変更

- iOS 8 と iOS 9 のサポートを打ち切りました。
- このバージョンから UserNotification.framework をアプリに組み込む必要があります。



### 5.6.0 (2021/07/20)

新機能

- アプリ起動中も一定期間ごとにアプリ内メッセージの取得が行われるようになります。

変更

- これまで1セッション中に同じメッセージは1度しか表示されない仕様でしたが、今回のアップデートにより、セッション中に同じメッセージが複数回表示されるようになります。



### 5.5.3 (2021/06/16)

修正

- アプリがIn-Appメッセージのディープリンクで画面遷移する場合に、key windowを用いた実装の場合で画面遷移に失敗する不具合を修正しました。



### 5.5.1 (2021/05/28)

修正

- デバイスを回転させたときのIn-Appメッセージの挙動を修正し、オリエンテーションの設定に従うようにしました。この修正でAndroid SDKでの挙動と同様となります。
- iOS WebViewの不具合により、HTML In-Appメッセージを表示したあとに一時的にHTML In-Appメッセージが回転しなくなる不具合を修正しました。



### 5.5.0 (2021/05/20)

新機能

- HTMLアプリ内メッセージの一部のテンプレートにて記述されたJavaScriptを利用できるようになりました。



### 5.4.0 (2021/03/08)

変更

- 軽微な不具合を修正しました。



### 5.3.0 (2021/02/01)

変更

- ユーザープロフィールおよびイベント名の先頭・末尾にスペースが含まれている場合、これを無視するよう変更しました。
- シルバーエッグレコメンドメッセージにおける内部処理を変更しました。

修正

- ソフトウェアキーボードの表示中にIn-Appメッセージが表示されたとき、キーボードが表示されたままになる問題を修正しました。



### 5.2.12 (2020/12/21)

修正

- 特定のUser Profile Keyによってアプリ起動時にアプリがクラッシュする問題を修正しました。
- 誤ったURLエンコーディングによってディープリンクを開けない問題を修正しました。



### 5.2.8 (2020/11/25)

修正

- ユーザーからSDKに渡されるデータの型チェックを改善しました。
- iOS の内部的なURLを、HTML In-Appメッセージのディープリンクとして使用できない問題を解決しました。
- UISceneを使用するアプリで非推奨のUIApplicationハンドラが実装されていると、プッシュ通知がトラッキングされない問題を解決しました。
- In-Appメッセージの表示向きを `UISupportedInterfaceOrientations` に依存しないようにしました。
- 複数画面に接続しているときに、タッチインタフェースがあるメイン画面にIn-Appメッセージが表示されるようになります。



### 5.2.2 (2020/10/22)

修正

- アプリがバックグラウンド時に稀にクラッシュしてしまう問題を修正しました。



### 5.2.0 (2020/10/07)

新機能

- HTMLアプリ内メッセージでiframeを利用したメッセージが表示できるようになりました。



### 5.1.0 (2020/08/11)

修正

- Repro SDKがXcode 12のアプリにリンクされた際に発生するwarningの修正しました。
- iOS14でのIDFA取得に関する対応をしました。



### 5.0.2 (2020/07/01)

修正

- イベントデータアップロードにおける軽微な不具合を修正しました。



### 5.0.1 (2020/06/25)

修正

- セッションの最後のデータアップロードで稀に成功しないバグを修正しました。



### 5.0.0 (2020/06/19)

新機能

- アプリがフォアグラウンド中にイベントやユーザープロフィールなどの情報が定期的にアップロードされるようになり、データの処理タイミングが早くなりました。

変更

- アプリ内メッセージ機能に関する以下のAPIの名称を変更しました。
  - `disableInAppMessageOnActive` → `disableInAppMessagesOnForegroundTransition`
- 以下のAPIを削除しました。
  - `showInAppMessage`
- 以下のAPIを追加しました。
  - `enableInAppMessagesOnForegroundTransition`

##### WARNING
今回のバージョンは修正範囲が広いため、一度v5.0.0を組み込んでリリースした後に、ダウングレードしてアプリをリリースすると不具合が発生する可能性がございます。ダウングレードは推奨いたしませんのでご注意ください。



### 4.8.0 (2020/05/20)

新機能

- プッシュ通知の機能に「ニュースフィード」の機能を追加しました。



### 4.7.1 (2020/04/08)

変更

- 「HTMLアプリ内メッセージ」機能の正式リリースに伴い、パフォーマンスを改善しました。



### 4.7.0 (2020/03/23)

新機能

- Reproのキャンペーン表示を、ユーザーの行動とリアルタイムで連動して行うことができるようになりました。
  - 詳細は [メッセージ表示トリガー](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md#in-app-message-trigger) をご覧ください。



### 4.6.2 (2020/03/05)

修正

- Unity2019.2バージョンとの互換性を改善する内部変更を行いました。

変更

- Xcodeの対応バージョンはXcode 11以上に引き上げられました。

##### WARNING
本リリースより、Xcode 11以上でビルドすることが必須になります。 [尚、App Storeへのアプリ提出も2020年4月30日よりXcode 11でビルドすることが必須となります。](https://developer.apple.com/news/?id=03042020b)



### 4.6.0 (2020/02/05)

修正

- SwiftUIなどXcode 11で導入された `UIScene` を利用したアプリで、アプリ内メッセージが表示されない不具合を修正しました。



### 4.5.1 (2020/01/22)

修正

- 「AIレコメンド・アプリ内メッセージ連携機能（クローズドβ）」における軽微な不具合を修正しました。



### 4.5.0 (2019/12/10)

新機能

- アプリ内メッセージ機能に「AIレコメンド・アプリ内メッセージ連携機能（クローズドβ）」を追加しました。



### 4.4.0 (2019/11/14)

変更

- `UIWebView` の利用は非推奨となったため、 `startWebViewTracking` メソッドのデリゲートには `WKNavigationDelegate` に準拠したオブジェクトのみを指定できるようになりました。

修正

- 特定のサードパーティ製ライブラリと併用した際、アプリケーションの起動時に例外が発生する問題を解決しました。



### 4.3.0 (2019/10/07)

新機能

- メッセージ内容を HTML と CSS でカスタマイズできる「HTMLアプリ内メッセージ（クローズドβ）」機能を追加しました。

##### NOTE
今回のバージョンから新しく `WebKit.framework` への依存が追加されます。CocoaPodsを利用する場合は、自動で依存が追加されるため特に作業は必要ありません。手動でSDKを導入している場合は、 `WebKit.framework` への依存を手動で追加する必要があります。詳細は [こちら](https://docs.repro.io/ja/dev/sdk/getstarted/ios.md#ios-setup-manually) をご覧ください。



### 4.2.0 (2019/08/23)

新機能

- UXオプティマイザー機能（クローズドβ）を追加しました。

修正

- 稀に他のサードパーティライブラリーの通信設定によって、アプリ内メッセージが常にタイムアウトするバグを修正しました。



### 4.1.0 (2019/07/18)

修正

- iOS 13でバナータイプのアプリ内メッセージが正常に表示されない問題を修正しました。



### 4.0.3 (2019/05/22)

変更

- 動画機能に関する以下のAPIを削除しました。
  - `startRecording`
  - `stopRecording`
  - `pauseRecording`
  - `resumeRecording`
  - `mask`
  - `unmask`
  - `maskWithRect`
  - `unmaskForKey`
  - `forceCaptureOnMainThread`
  - `enableRecordingWhileViewAnimations`
  - `disableRecordingWhileViewAnimations`
- Swift版APIのメソッド名およびシグニチャーが変更されました。変更されたメソッドの一覧については、以下の変更一覧を参照してください。
  また変更後のAPIの使用方法については開発ガイドを参照してください。

  * [iOS SDK 4.0.3 Swift版API 変更一覧](https://docs.repro.io/ja/releases/sdk/ios/release4-0-3.md)



### 3.3.2 (2019/04/19)

変更

- 日本国外の一部のアプリにおいて、アプリ内メッセージの画像ダウンロードのタイムアウト時間を調整しました。



### 3.3.1 (2019/04/11)

修正

- アプリがGoogle Firebase SDKを利用している場合、プッシュ通知の開封が記録されない不具合を修正しました。



### 3.3.0 (2019/03/22)

<!-- - 仕様変更前: -->

変更

- アプリがフォアグラウンド中にプッシュ通知を **受信** した場合の仕様を変更しました。

  これまでは、受信しただけで直接開封として記録し、さらにカスタム・スキームのURLが指定されていた場合はSDKが自動でURLを開いていました。

  今後は、受信しただけではSDKは何も処理しません。これにより直接開封数の計測精度が向上します。

  なお、プッシュ通知を **開封** した場合の仕様はこれまで通りです。また、アプリがバックグラウンド中に受信 / 開封した場合の仕様もこれまで通りです。変更前後の仕様の詳細は以下をご覧ください。
  - 仕様変更前:

| アプリがフォアグラウンド | - 受信 : 直接開封として記録/URL開く - 開封 : 直接開封として記録/URL開く |
| --- | --- |
| アプリがバックグラウンド | - 受信 : 何もしない - 開封 : 直接開封として記録/URL開く |
  - 仕様変更後:

| アプリがフォアグラウンド | - 受信 : 何もしない (今回変更した仕様) - 開封 : 直接開封として記録/URL開く |
| --- | --- |
| アプリがバックグラウンド | - 受信 : 何もしない - 開封 : 直接開封として記録/URL開く |

修正

- バナータイプのアプリ内メッセージの表示位置が正しくない、または表示されない不具合を修正しました。



### 3.2.2 (2019/03/05)

修正

- アプリがBackground Fetchの処理を実行する際に、SDKからReproのサーバに不要な通信が発生する不具合を修正しました。
- アプリ内メッセージの閉じるボタンのタップ可能エリアが狭くなっていた不具合を修正しました。



### 3.2.0 (2019/02/14)

変更

- アプリがバックグラウンド中の処理時間を大幅に短くしました。
  - SDKはアプリがバックグラウンドに遷移した際にReproのサーバーにデータを送信しています。これまではバックグラウンド後に最大3分程度動作していましたが、今後はバックグラウンド後1 ~ 2秒程度で動作を停止します。
- 動画機能に関する主要なコードを削除し、動画機能が動作しないようにしました。以下のAPIを呼び出しても問題ありませんが何も実行されません。
  - `startRecording`
  - `stopRecording`
  - `pauseRecording`
  - `resumeRecording`
  - `mask`
  - `unmask`
  - `maskWithRect`
  - `unmaskForKey`
  - `forceCaptureOnMainThread`
  - `enableRecordingWhileViewAnimations`
  - `disableRecordingWhileViewAnimations`

  #### WARNING
  録画関連APIは削除されました。2019年5月22日現在、これを利用することはできません。

修正

- ダイアログタイプとオーバーレイタイプのアプリ内メッセージのレイアウトが稀に崩れる不具合を修正しました。



### 3.1.0 (2019/01/30)

新機能

- オプトアウト機能を追加しました。
  - オプトアウト機能を利用することで、SDKによるデータ収集とアプリ内メッセージの表示を無効にできます。詳細は [こちら](https://docs.repro.io/ja/dev/sdk/optout/index.md) をご覧ください。

変更

- `UIViewController` の `viewWillAppear/viewWillDisappear` でイベントトラックした場合でも、アプリ内メッセージを表示可能となりました。



### 3.0.6 (2018/11/22)

変更

- SDK内部で使用しているグローバルSymbol名の一部を変更し、Symbol名衝突によるリンクエラーを解消しました。



### 3.0.4 (2018/11/14)

変更

- バナータイプのアプリ内メッセージのフォントサイズを大きくし、メッセージの視認性を高めました。



### 3.0.3 (2018/10/25)

変更

- これまで以下の端末ではiOS12以上の場合に録画機能を無効としていましたが、iOS SDK 3.0.3で録画可能となりました。一部制限事項がありますので注釈をご覧ください。
  - iPhone X
  - iPhone 8 Plus
  - iPhone 8
  - iPhone 7 Plus
  - iPhone 7

  #### NOTE
  **これまで録画機能を無効としていた背景**

  iOS12の不具合の影響で、iOS12以上の一部端末で録画機能を利用すると、端末の負荷が増大するという現象が発生していました。このため、これまでiOS12以上の一部端末では録画機能を無効としていました。

  **iOS SDK 3.0.3での暫定措置と制限事項**

  iOS SDK 3.0.3では、暫定的な措置として端末の負荷を上げずに録画できるようになりましたが、以下の制限事項があります。
  - アニメーション効果が録画されない
  - 一部の文字の色が画面と動画で異なる
  - 半透明の部分が画面と動画で異なる
  - Sprite Kitで作成された画面が録画されない

  **今後の見通し**

  AppleにはiOS12の不具合を報告済みです。Apple側の修正が完了次第、iOS SDK 3.0.3の暫定措置をやめて、制限事項無しで録画できるSDKのリリースを検討します。



### 3.0.2 (2018/10/23)

変更

- アプリからSafariや他のアプリを起動してバックグラウンドに移行した場合も、すぐにセッションを終了するようになりました。バージョン3.0.1までのiOS SDKは、すぐにセッションを終了せずに2分30秒経過するまでセッションをポーズしていました。セッションの終了については [こちら](https://docs.repro.io/ja/dev/sdk/session.md#stop-session) をご覧ください。



### 3.0.1 (2018/09/20)

変更

- UIWebViewでiframeを含むWebページをロードした場合に、マスクが外れたりページ遷移後もマスクが残り続ける不具合を修正しました。
  - iOS SDK 3.0.1以上をご利用になる場合、Webページからは最新版の `cdn.reproio.com/js/v4/repro.js` をロードしてください。なお、ロードするURLを `cdn.reproio.com/js/v3/repro.js` から `cdn.reproio.com/js/v4/repro.js` にアップデートする場合は、「購入」イベントをトラックするAPIの仕様が変更となることに注意してください。詳しくは [こちらの変更点](#ios-2-11-1) をご覧ください。



### 3.0.0 (2018/08/24)

変更

- データアップロードの処理を変更しました。
  - iOS SDK 3.0.0未満は、2019年6月24日以降にセッションデータをアップロードできなくなります。
  - そのため、2019年6月24日までにiOS SDK 3.0.0以上にアップデートしてください。



### 2.13.0 (2018/08/08)

新機能

- iOS12に対応しました。
  - iOS12以上の端末で録画機能をご利用いただくには、SDKを2.13.0にアップデートしてください。SDK 2.13.0未満をiOS12以上の端末で動作させた場合は、録画機能が無効となります。詳細は以下の注釈をご覧ください。

    なお、録画機能以外はSDKバージョンおよびOSバージョンにかかわらず、これまで通りご利用いただけます。

    #### NOTE
    SDKは、動画アップロード時に端末のネットワーク接続状況をチェックし、管理画面の **設定 > 録画設定 > アップロード許可ネットワーク** に合致している場合のみアップロードする仕様となっています。

    このネットワーク接続状況のチェックにSDK 2.13.0未満で利用していたAPIが、Appleの仕様変更によりiOS12以上で利用できなくなりました。

    ネットワーク接続状況を誤判定して意図しない状況で動画がアップロードされることを防ぐため、SDK 2.13.0未満をiOS12以上の端末で動作させた場合は、録画機能が無効となります。

    なお、SDK 2.13.0未満でもiOS11以下の端末ではこれまで通り録画機能をご利用いただけます。

変更

- 横向きで表示される際のアプリ内メッセージのレイアウトを変更しました。



### 2.12.2 (2018/07/19)

変更

- SDKのdeployment targetを6.0から8.0に変更しました。
  - これにより、SDKの動作対象が6.0から8.0に変更となります。動作対象の詳細は [こちら](https://docs.repro.io/ja/requirements.md) をご覧ください。



### 2.11.1 (2018/06/29)

変更

- アプリ内メッセージの表示待ち時間が短くなるよう改善しました。
  - アプリ起動後にアプリ内メッセージの画像を予めダウンロードするようになりました。予めダウンロードが完了している場合は、トリガーイベント発生時に待ち時間無しでアプリ内メッセージが表示されます。
  - また、ダウンロード未完了の時にトリガーイベント発生した場合でも、3秒以内にダウンロード完了できない場合はアプリ内メッセージの表示をキャンセルするようになりました。
- 「購入」イベントの `value` と `currency` プロパティの指定が必須になりました。詳細は [購入](https://docs.repro.io/ja/dev/sdk/tracking.md#track-purchase) をご覧ください。
  - APIのシグネチャーを変更しました。 `trackPurchase` の第2引数で `value` を指定し、第3引数で `currency` を指定してください。
    ```diff
    // Objective-C
    - [Repro trackPurchase:@"content_id" properties:nil];
    + [Repro trackPurchase:@"content_id" value:5000.0 currency:@"JPY" properties: nil];

    // Swift
    - Repro.trackPurchase("content_id", properties: nil)
    + Repro.trackPurchase("content_id", value: 5000.0, currency: "JPY", properties: nil)
    ```
  - WebViewから「購入」イベントをトラックする場合も `value` と `currency` が必須となります。
    - APIシグネチャーを変更した `v4/repro.js` を公開しました。`trackPurchase` の第2引数で `value` を指定し、第3引数で `currency` を指定してください。
      ```diff
      <head>
      -  <script src="//cdn.reproio.com/js/v3/repro.js" type="text/javascript" charset="utf-8"></script>
      +  <script src="//cdn.reproio.com/js/v4/repro.js" type="text/javascript" charset="utf-8"></script>
      </head>

      ...

      repro.trackPurchase("content_id", 5000.0, "JPY", {
        content_name: "Slim Jeans"
      });
      ```
    - なお、古い `v3/repro.js` をご利用の場合でも `value` と `currency` の指定は必須となります。 `v3/repro.js` をご利用し続ける場合は、 `trackPurchase` の第2引数に渡すオブジェクトで `value` と `currency` を指定してください。
      ```diff
      repro.trackPurchase("content_id", 5000.0, "JPY", {
        content_name: "Slim Jeans"
      });
      ```



### 2.10.11 (2018/06/19)

修正

- Firebase Cloud MessagingのSDKを導入しているアプリで、UNUserNotificationCenterのdelegateプロパティを複数回セットすると、プッシュ通知受信時にアプリクラッシュする不具合を修正しました。
- AVPlayerを使った画面を録画すると、録画された動画が途中で途切れる不具合を修正しました。
  - これまで通りAVPlayerは録画対象外であり、録画された動画上はAVPlayerの表示領域が黒一色に見えます。



### 2.10.7 (2018/05/11)

変更

- ユーザーIDがセットされていない状態で記録されたユーザープロフィールは、ユーザーIDをセットした後に引き継がれるように変更しました。



### 2.10.4 (2018/04/16)

修正

- 通信回線が低速の場合にアプリをフォアグラウンドからバックグラウンドに何度も切り替えると、セッションデータのアップロードに失敗してリトライし続ける不具合を修正しました。
- AppDelegate に window プロパティが存在しない場合、アプリ内メッセージを閉じるとクラッシュする不具合を修正しました。



### 2.10.0 (2018/03/20)

新機能

- アプリ内メッセージでコントロールグループ機能が利用できるようになりました。詳細は [こちら](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md) をご覧ください。



### 2.9.11 (2018/03/02)

修正

- 通信回線が低速の場合に、アプリをバックグラウンドからフォアグラウンドに切り替えるとしばらくアプリが応答しなくなる不具合を修正しました
- SDKのヘッダファイル `RPRUserProfileGender.h` のファイル末尾に改行文字を付与しました
  - これにより、SDKを組み込んだアプリを `-Werror -Wnewline-eof` を指定してビルドしてもビルドエラーとならなくなります



### 2.9.1 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。



### 2.9.0 (2018/01/18)

新機能

- アプリ内メッセージのボタン押下数の計測に対応しました。計測されたボタン押下数は管理画面から確認できます。詳細は [こちら](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md#inapp-measurement) をご覧ください。



### 2.8.6 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。



### 2.8.5 (2017/12/18)

変更

- アニメーション中に録画を継続するかを切り替えることが可能になりました。デフォルトでは録画をスキップします。
- アプリ内メッセージの画像を提供するサーバと3~6秒以内に通信を開始できない場合、アプリ内メッセージの表示をキャンセルするようになりました。



### 2.8.0 (2017/11/16)

新機能

- アプリを初めて起動したユーザーを対象にアプリ内メッセージを配信する機能を追加しました。



### 2.7.4 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。



### 2.7.3 (2017/10/31)

修正

- 稀にセッションの保存に失敗する不具合を修正しました。



### 2.7.0 (2017/10/19)

新機能

- 指定したイベントが発生したタイミングで録画開始するトリガー録画機能を追加しました。



### 2.6.10 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。



### 2.6.9 (2017/10/05)

修正

- 画面遷移時に稀に録画が途切れる不具合を修正しました。
- スクロール録画中に稀にクラッシュする不具合を修正しました。



### 2.6.8 (2017/09/21)

修正

- UIWebView/WKWebViewを継承した場合、WebViewのマスクが機能しない不具合を修正しました。



### 2.6.5 (2017/09/07)

新機能

- iOS 11およびXcode 9に対応しました。
  - 管理画面の **設定 > 録画設定 > スクロール録画** をONにした場合、録画中にXcode 9で警告が表示される場合があります。その場合は録画開始前に `[Repro forceCaptureOnMainThread]` を呼び出してください。

修正

- 横向きにしたiPadでダイアログタイプのアプリ内メッセージを表示した場合に、閉じるボタンが画面からはみ出る不具合を修正しました。



### 2.6.0 (2017/08/23)

新機能

- 標準ユーザープロフィール(ユーザーを絞り込む上で典型的なプロフィール)をセットするためのAPIを追加しました。詳細は [ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md) を参照してください。



### 2.5.3 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。



### 2.5.2 (2017/08/04)

新機能

- UIWebView と WKWebViewで標準イベントをトラックするためのAPIを追加しました。
  - HTMLから読み込むrepro.jsのURLを変更する必要があります。repro.jsの使い方の詳細は [こちら](https://docs.repro.io/ja/dev/sdk/webview.md) を参照してください。

  ```diff
   <head>
   ...
  -   <script src="//cdn.reproio.com/js/v2/repro.js" type="text/javascript" charset="utf-8"></script>
  +   <script src="//cdn.reproio.com/js/v3/repro.js" type="text/javascript" charset="utf-8"></script>
   ...
   </head>
  ```



### 2.5.0 (2017/07/03)

新機能

- 標準イベント(ユーザーの行動分析を行う上で典型的なイベント)をトラックするためのAPIを追加しました。詳細は [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md) を参照してください。

修正

- 録画中にマスク追加・削除すると稀にクラッシュする不具合を修正しました。
- iOS 10.1以降で端末を回転させると稀にアプリ内メッセージのレイアウトが崩れる不具合を修正しました。



### 2.4.1 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。



### 2.4.0 (2017/05/23)

新機能

- アプリ内メッセージの色をカスタマイズできるようになりました。詳細は [アプリ内メッセージ](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md) を参照してください。



### 2.3.2 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。



### 2.3.1 (2017/05/19)

新機能

- 「初回起動」イベントの自動トラッキング機能を追加しました

修正

- 録画中に稀にクラッシュする不具合を修正しました
- Viewのアニメーション中にマスクがずれる不具合を修正しました



### 2.2.18 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。



### 2.2.17

変更

- これまでiOS SDKに同梱されていたCocos2d-x用のReproCpp.h/ReproCpp.mmは削除され、新しく [Repro Cocos2d-x SDK](https://github.com/reproio/repro-cocos2dx-sdk) となりました。Repro Cocos2d-x SDKへの更新手順は [こちら](https://docs.repro.io/ja/releases/sdk/cocos2d-x/upgrade.md) をご覧ください。

修正

- WebViewでキーボードを表示した際に録画が途切れる不具合を修正しました。



### 2.2.13

修正

- 管理画面の **設定 > 録画設定 > スクロール録画** をOFFに設定していても、画面スクロール時に録画されてしまう不具合を修正しました



### 2.2.9

修正

- セッション終了時に稀にクラッシュする不具合を修正しました



### 2.2.2

新機能

- ダイアログタイプのアプリ内メッセージで [画像のみのレイアウト](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md#dialog-image-only) を選択できるようになりました

改善点

- [ユーザーID](https://docs.repro.io/ja/dev/sdk/user-id.md) とアプリバージョン名の文字列長をチェックするようにしました
  - [ユーザーID](https://docs.repro.io/ja/dev/sdk/user-id.md) は最大191文字です。最大文字数を超える場合は192文字以降を切り捨てます
  - アプリバージョン名は最大32文字です。最大文字数を超える場合は33文字以降を切り捨てます
- `setIntUserProfile:forKey:` の第1引数の型を `int` から `NSInteger` に変更しました
  - Objective-Cをお使いの場合はソースコードの変更は不要です
  - Swiftをお使いの場合で、第1引数に `Int32` 型の変数を渡していた場合、 `Int` 型への変換が必要となります

  ```diff
  let age:Int32 = 25;
  - Repro.setUserProfile(age, forKey:"age");
  + Repro.setUserProfile(Int(age), forKey:"age");
  ```



### 2.1.13 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。



### 2.1.12

修正

- Webページのロード直後にマスクが外れるバグを修正しました。

### 2.1.3

修正

- CTA URLがハッシュ(#)を含む場合にエンコードされないようにしました。

### 2.1.0

新機能

- プッシュ通知開封時に、ディープリンク、URLを自動で開く機能を追加しました。
- UserNotifications frameworkを使用しているアプリでのプッシュ通知の開封記録に対応しました。

修正

- プッシュ通知の開封が記録されないバグを修正しました。



### 2.0.10 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。

### 2.0.9

変更

- 表情録画機能を削除しました。
- デフォルトログレベルをErrorに変更しました。

修正

- バナータイプのアプリ内メッセージが閉じられたときにCTAイベントがトラックされる不具合を修正しました。

### 2.0.6

変更

- iOS 10においてWebページを開く際に `openURL:options:completionHandler:` を使用するよう変更しました。

修正

- `track:` というメソッド名がAppleの静的解析でプライベートAPIであると誤検出されるため、変更しました。

### 2.0.4

修正

- UIWebView/WKWebView のマスキングが正常動作しないバグを修正しました。



### 2.0.0

新機能

- ユーザープロフィールで文字列以外の型のデータを登録できるようになりました。下記のAPIをご利用ください。
  - `setIntUserProfile:(int)value forKey:(NSString*)key`
  - `setDoubleUserProfile:(double)value forKey:(NSString*)key`
  - `setDateUserProfile:(NSDate*)value forKey:(NSString*)key`
- `setUserProfile:(NSString*)value forKey:(NSString*)key` と `setUserProfile:(NSDictionary *)profile` は削除されました。  `setStringUserProfile:(NSString*)value forKey:(NSString*)key` をお使いください。
  ```diff
  - [Repro setUserProfile:@"Developer" forKey:@"Job"];
  + [Repro setStringUserProfile:@"Developer" forKey:@"Job"];
  ```

修正

- アプリ内メッセージのレイアウトが崩れるバグを修正しました。



### 1.7.35 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。

### 1.7.34

改善

- アプリをスワイプして強制終了させた場合でもセッションと動画が保存されるように修正しました。

### 1.7.30

改善

- UIWebView/WKWebView内で遷移をした場合にマスクを解除するようにしました

修正

- ログを書き込む際に稀に発生するクラッシュを修正しました。
- アプリをビルドできなくなる場合があるバグを修正しました。
- アプリ内メッセージのレイアウトが崩れるバグを修正しました。

### 1.7.25

改善

- アプリ内メッセージの画像をロード中にプログレスダイアログを表示するようにしました。

修正

- WebViewでページをロードした直後にイベントトラッキングに失敗する不具合を修正しました。WebViewトラッキングをご利用されている場合は、HTMLから読み込むJavaScriptファイルのURLを変更してください。
  ```diff
   <head>
   ...
  -   <script src="//cdn.reproio.com/js/v1/dummy.repro.js" type="text/javascript" charset="utf-8"></script>
  +   <script src="//cdn.reproio.com/js/v2/repro.js" type="text/javascript" charset="utf-8"></script>
   ...
   </head>
  ```

### 1.7.19

変更

- `enableCrashReporting()` API を廃止しました。

### 1.7.16

修正

- アプリ内メッセージの画像を表示する際のクラッシュを修正しました。

### 1.7.15

新機能

- `getDeviceID` と `getUserID` API を追加しました。

変更

- ユーザープロフィールのキーと値の文字列長を制限しました。

修正

- アプリをkillした際に、アプリ内メッセージが表示済みにならないバグを修正しました。
- CTA URLが設定されていない場合にCTAイベントをトラックできないバグを修正しました。

### 1.7.9

修正

- アプリ内メッセージが2回表示される可能性を軽減しました。

### 1.7.6

改善

- マスキングの安定性を改善しました。
- イベントトラッキングの安定性を改善しました。

### 1.7.3

修正

- セッションデータのアップロードの遅延を改善しました。
- アプリ内メッセージが2回表示される可能性を軽減しました。
- デフォルトのオリエンテーション設定をもたないアプリにおいて、アプリ内メッセージのデフォルトの向きを指定するように修正しました。

### 1.7.0

新機能

- イベントトラッキング時にアプリ内メッセージを表示する機能を追加しました。



### 1.6.5 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。

### 1.6.4

修正

- クラッシュレポート機能がシグナルをキャッチした際に稀に発生するクラッシュを修正しました。

### 1.6.0

新機能

- UIWebView と WKWebView のマスキング機能を追加しました。

修正

- ビルドワーニングを修正しました。
- セッションが重複してアップロードされる可能性のあるバグを修正しました。
- マスキング中にクラッシュする可能性のあるバグを修正しました。



### 1.5.2 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。

### 1.5.1

改善

- アプリ内メッセージのパターンを追加しました。
  - ダイアログタイプのメッセージを使えるようになりました。
  - メッセージ中にボタンを2つ作成できるようになりました。

変更

- 非推奨のAPIを削除しました。



### 1.4.28 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。

### 1.4.27

変更

- イベント名の文字列の長さを255文字に制限しました。

### 1.4.22

改善

- アップロードの安定性を改善しました。

修正

- 表情録画機能で、ユーザーがカメラへのアクセスを拒否したときに発生する画面録画が動作しなくなるバグを修正しました。
- Localyticsを同時に利用している場合に発生するクラッシュを修正しました。
- UIイベントトラッキング（プライベートベータ) のバグを修正しました。

### 1.4.14

修正

- Apptimzeを同時に利用している場合に発生するクラッシュを修正しました。
- C++のユーザープロフィールAPIのバグを修正しました。
- 日本語で登録したイベント名の文字化けに対応しました

### 1.4.9

改善

- アプリ内メッセージがランドスケープモードに対応しました。
- アプリ内メッセージで大きい画像が使えるようになりました。
- C++向けのユーザープロフィールAPIを追加しました。

変更

- ユーザビリティテスティング機能を削除しました。

修正

- アプリ内メッセージのCTAに日本語を使えるように修正しました。

### 1.4.0

新機能

- ユーザープロフィール: プッシュ通知やアプリ内メッセージの配信対象をユーザーの属性情報でセグメントできるようになります。 [詳細はこちらをご覧ください](http://docs.repro.io/en/api/user-profile.html)

修正

- UIイベントトラッキング(プライベートベータ)が意図せず動作するバグを修正しました。
- セッション終了時にクラッシュが発生する可能性のあるバグを修正しました。
- Reproが有効になっていない場合に、稀にセッションが開始してしまうバグを修正しました。

### 1.3.23

修正

- アプリがバックグラウンドに移った直後に稀に発生するクラッシュを修正しました。
- iOS 6 においてセッションがアップロードされないバグを修正しました。

### 1.3.19

改善

- Reachabilityを削除しました。
  - iOS 9においてバグが報告されていたため、Reachabilityへの依存を削除しました。
  - **注意:** Reachabilityのかわりに `CoreTelephony.framework` を使うよう変更されています。Linked Frameworks and Libraryies へ追加するのを忘れないようにお願い致します。
- SDKからWeb Viewトラッカーをロードするよう変更しました。
  - `repro://` に意図せずアクセスするバグを解消するため、SDK内からWeb Viewトラッキング用のJavaScriptをロードするように変更しました。

### 1.3.15

変更

- iOS 6を再びサポートしました。
  - ただし、録画とユーザビリティテスティングは利用できません。

### 1.3.14

修正

- イベントプロパティが保存されないバグを修正しました。

### 1.3.13

修正

- Xcode 6 でビルドした際に、シミュレーター用にビルドできなくなる不具合を修正しました。
- 録画中にクラッシュする可能性のあるバグを修正しました。

### 1.3.10

改善

- デバイスの時計が正しく設定されていない場合に、トラックされたデータの時間を自動的に調整するよう変更しました。
- ユーザーIDを永続化するよう変更しました。

修正

- Reproが無効となっている、または、データポイントのリミットに到達している場合にトラックするとクラッシュするバグを修正しました。
- App Storeにアプリをアップロードする際のWarningを修正しました。
- ディープリンクを利用中、意図せず録画がポーズしてしまうバグを修正しました。
- Web view トラッキング中に発生する101エラーに対応しました。

### 1.2.10.1

修正

- ReproSDKResourcesが原因で、App Storeにアプリをアップロードできなくなるバグを修正しました。

### 1.2.10

新機能

- iOS 9 をサポートしました。
  : - Bitcode
      : - Bitcode を有効にしました。
    - ATS
      : - アップロード処理を修正しました。
        - **注意:** ATSを有効にしている場合、iOS 9ではアプリ内メッセージとWebViewトラッキングは10/1までは動作しません。
    - スプリットスクリーン
      : - 画面録画を修正しました。

改善

- アップロード処理を大幅に改善しました。
  - **注意:** 本バージョンより、 MobileCoreServices.framework が必須となります。
- C++アプリ向けのアプリ内メッセージのAPIを追加しました。

修正

- アプリ内メッセージが表示されないバグを修正しました。
- タッチのトラッキングが失敗するバグを修正しました。
- ユーザビリティテスティングがローカライゼーション設定によっては動作しなくなるバグを修正しました。

### 1.0.5

新機能

- アプリ内メッセージ

変更

- iOS 6 を非サポートとしました。
- `-ObjC` リンカーフラグを使わなくてすむよう変更しました。
- スクロール中の録画のバグを修正しました。

### 0.10.4.1

修正

- プッシュ通知のバグを修正しました。

### 0.10.4

新機能

- プッシュ通知

### 0.9.11

修正

- 起動時に重い処理を実行するアプリにおいてセッションが開始しないバグを修正しました。

### 0.9.8

修正

- 録画機能の安定性を向上しました。
  - 録画のAPIを連続して呼ぶと正しく動作しなくなるバグを修正しました。
  - Webサイトを開いた場合の自動ポーズを修正しました。
- 有効なユーザビリティテスティングが設定されていない場合に、 `enableUsabilityTesting` が呼ばれると、セッションが開始されなくなるバグを修正しました。

### 0.9.7

新機能

- スクロール中に録画停止する機能を追加しました。

修正

- カスタマイズされてUIWindowを表示中の画面録画のバグを修正しました。
- OSのパッチバージョンを取得できていないバグを修正しました。
- ユーザビリティテスティングのviewの矢印の色を変更しました。

### 0.8.0

変更

- openURLが呼ばれた際に録画が自動でポーズするように変更しました。
- ポーズの時間を2.5分に制限しました。
- armv7sをサポートしました。
- アップロードの間隔を変更しました。

修正

- FPSが1のときにクラッシュするバグを修正しました。
- ユーザビリティテスティング中にデバイスを回転するとクラッシュするバグを修正しました。
- ユーザビリティテスティングのnextボタンが表示されないバグを修正しました。

### 0.4.7

修正

- ユーザビリティテスティング中に画面録画が正しく動作しないバグを修正しました。

### 0.4.6

改善

- WKWebViewでのイベントラッキングに対応しました。
- ユーザビリティテスティングを改善しました。
  - ランドスケープモードでのレイアウトを調整しました。
- コンフィギュレーションを改善しました。
  - リトライするように変更しました。

修正

- マスキングとレコーディングのバグを修正しました。

### 0.4.5

改善

- 画面録画のパフォーマンスを改善しました。

### 0.4.4

修正

- アップロード時にクラッシュするバグを修正しました。

### 0.4.3

改善

- 録画機能を改善しました。
  - 表情録画のポーズ/再開に対応しました。
  - 画面録画のファイルサイズを削減しました。
  - メモリーワーニング発生時に録画を停止するよう変更しました。
- マスキング機能を改善しました。
  - inputフィールドを自動でマスクするよう対応しました
  - unmask APIを追加しました。
- ログレベルを変更できるようにしました。
- クラッシュレポートを改善しました。
  - シグナルをキャッチできるように変更しました。

### 0.4.2

改善

- アップロードの安定性を改善しました。

### 0.4.1

改善

- マスキング機能を改善しました。
  - カメラロールは録画できないように変更しました。
- ユーザビリティテスティングの安定性を向上させました。

### 0.4.0

改善

- 画面録画の安定性を向上させました。
- ユーザビリティテスティングの安定性を向上させました。

### 0.3.9

新機能

- Cordovaをサポートしました。
- Cocos2d-xをサポートしました。

変更

- armv7sを非サポートとしました。

修正

- デバイスの回転検知を修正しました。

### 0.3.8

修正

- クラッシュレポートのバグを修正しました。
- アンケート機能のバグを修正しました。

### 0.3.7

改善

- armv7sをサポートしました。

修正

- C++ ライブラリに依存しているアプリにおけるビルドエラーを修正しました。

### 0.3.6

新機能

- ユーザビリティテスティング
  - 詳しくはこちらをご覧ください: [http://doc.repro.io/ios/api/usability-testing](http://doc.repro.io/ios/api/usability-testing)

改善

- マスキング機能を改善しました。
- アンケート機能を改善しました。

### 0.3.5

改善

- タッチしたときにクラッシュするバグを修正しました。

### 0.3.4

修正

- マスキングのバグを修正しました。
- マスクの色を修正しました。
- iOS 8でキーボードを開いたときにタッチをトラックしないように修正しました。

### 0.3.3

- 表情録画機能のバグを修正しました。

### 0.3.2

新機能

- 録画開始時の確認ダイアログをカスタマイズできるように変更しました。

### 0.3.1

- リンク時のバグを修正しました。

### 0.3.0

改善

- iOS 8とXcode 6をサポートしました。

変更

- API変更
  - パブリックヘッダを `Repro.h` に変更しました。
  - API変更については、 [ドキュメント](http://doc.repro.io) をご覧ください。
- 録画しないでイベントトラッキングできるように変更しました。
  - 録画の開始と終了のタイミングをいつでも選べるようになりました。
  - イベントトラッキングは管理画面で有効にすれば自動的に開始します。

### 0.2.8

新機能

- UIWebViewのトラッキングに対応しました。

変更

- AWS Framework への依存をなくしました。
- API変更: setUserAnnotation -> setUserID

修正

- マスキングのバグを修正しました。
- 画面遷移中のマスキングのバグを修正しました。
- 端末の向きを変更した際のマスキングのバグを修正しました。

### 0.2.7

新機能

- クラッシュレポート

修正

- 表情録画を再開する際のバグを修正しました。

### 0.2.6

新機能

- カスタムイベントのトラッキングに対応しました。
- 録画中の端末の向き変更をトラックできるようにしました。

修正

- 最大録画時間のバグを修正しました。
- タッチと動画のラグを修正しました。

### 0.2.5

修正

- 軽微なバグを修正しました。

### 0.2.4

新機能

- 座標指定のマスキング機能を追加しました。

修正

- 軽微なバグを修正しました。

### 0.2.3

新機能

- 録画のポーズ・再開機能を実装しました。
- ユーザーIDをセットする機能を追加しました。

修正

- 軽微なバグを修正しました。

### 0.2.2

修正

- 軽微なバグを修正しました。

### 0.1.8

- 初回リリース

---

objc,swift

## iOS SDK 更新手順

### Swift Package Manager

Xcodeを開き、左側のプロジェクトナビゲータから `Repro` を右クリックし [Update Package] で更新してください。



##### NOTE
CocoaPodsは2026年12月2日に中央リポジトリ（Trunk）が「読み取り専用（read-only）」に変更されることが予定されています。
 
変更以降にリリースされるRepro iOS SDKはCocoaPodsでの利用ができなくなるため、Swift Package Managerの利用を推奨しています。
 
なお、変更以前にリリースされたSDKについては引き続きCocoaPodsでの利用が可能です。
 
詳細は [CocoaPodsの公式ドキュメント](https://blog.cocoapods.org/CocoaPods-Specs-Repo/) をご確認ください。
 
※2026年4月24日時点の情報です。
 

### CocoaPods

CocoaPodsをご利用の場合は、下記のコマンドを実行してください。

```sh
$ pod update Repro
```

#### トラブルシューティング

最新のiOS SDKがインストールされない場合は以下を確認してください。

**Podfileで古いiOS SDKバージョンを指定していないか**

以下のようにPodfileで古いiOS SDKバージョンが指定されている場合、最新のiOS SDKがインストールされません。

```ruby
target 'YOUR-PROJECT-NAME' do
    pod "Repro", "0.0.1"
end
```

バージョンの指定を削除してから `pod update Repro` を実行してください。

```diff
target 'YOUR-PROJECT-NAME' do
-       pod "Repro", "0.0.1"
+       pod "Repro"
end
```

**ローカルマシンのCocoaPodsリポジトリが更新されているか**

CocoaPodsリポジトリが古い場合、最新のiOS SDKがインストールされません。以下のコマンドを実行してCocoaPodsリポジトリを更新してからインストールを実行してください。

```sh
$ pod repo update
$ pod update Repro
```

### SDKをダウンロードしてインストールする

SDKをダウンロードしてプロジェクトにインストールしている場合は、下記の手順で更新してください。

#### 古いSDKを削除する

プロジェクトから `Repro.xcframework` への参照を削除してください。



#### 新しいSDKをインストールする

[SDKをダウンロードしてインストールする](https://docs.repro.io/ja/dev/sdk/getstarted/ios.md#ios-setup-manually).

---

objc, swift

## 導入: iOS

### SDKをインストールする



#### Swift Package Manager (推奨)

Repro SDKは Swift Package Manager を使ってインストールすることができます。

Xcodeの **File** > **Add Packages...** でSwift Package Managerのパッケージ選択画面を開きます（古いXcodeでは、**File** > **Swift Packages** > **Add Package Dependency...** から開くことができます）。

検索欄に `https://github.com/reproio/repro-ios-sdk` と入力すると、Repro iOS SDKが選択できます。



`Add Package` ボタンをクリックするとパッケージの検証が行われます。その後もう一度 `Add Package` ボタンをクリックするとプロジェクトにSDKが追加されます。正しくインストールされたか、プロジェクト設定で確認することができます。

詳細は [Appleの公式ドキュメント](https://developer.apple.com/documentation/xcode/adding-package-dependencies-to-your-app) をご確認ください。

##### WARNING
Xcode ~13.0 の環境では、Swift Package Managerのキャッシュにリポジトリがクローンされることが原因で、`Add Package` ボタンをクリック後にしばらく時間がかかることがあります。この挙動は将来的に変更されるものと推測しています。



#### CocoaPods

Repro SDKは [CocoaPods](http://cocoapods.org/pods/Repro) を使ってインストールすることができます。

以下の行をプロジェクトの Podfile に追加してください。

```ruby
target 'YOUR-PROJECT-NAME' do
        pod "Repro"
end
```

下記のコマンドを実行してください。

```sh
$ pod install
```

SDKのインストールに成功したら、 `YOUR-PROJECT-NAME.xcworkspace` を開き [Repro をセットアップしてください](#ios-setup) 。

##### NOTE
CocoaPodsは2026年12月2日に中央リポジトリ（Trunk）が「読み取り専用（read-only）」に変更されることが予定されています。
 
変更以降にリリースされるRepro iOS SDKはCocoaPodsでの利用ができなくなるため、Swift Package Managerの利用を推奨しています。
 
なお、変更以前にリリースされたSDKについては引き続きCocoaPodsでの利用が可能です。
 
詳細は [CocoaPodsの公式ドキュメント](https://blog.cocoapods.org/CocoaPods-Specs-Repo/) をご確認ください。
 
※2026年4月24日時点の情報です。
 



#### SDKをダウンロードしてインストールする

CocoaPodsとSwift Package Managerを利用していない場合、 [Repro-iOS-SDK の最新リリース版](//github.com/reproio/repro-ios-sdk/releases) をダウンロードし、手動でインストールすることもできます。

ダウンロードした.zipファイルに含まれた `Repro.xcframework` をプロジェクトディレクトリに移動した後にXcodeの **File** > **Add Files to "AppName"** でプロジェクトに追加してください。

##### 必要なフレームワーク

最後に、以下リストのFrameworkもプロジェクトの **Targets** > **Build Phases** > **Link Binary With Libraries** にて追加してください。

* **SystemConfiguration.framework**
* **WebKit.framework**
* **UserNotifications.framework**

##### NOTE
iOS 14でリリースされた新機能「App Clips」はまだサポートしておりません。「App Clips」へのRepro SDKの導入は非推奨となっております。



### セットアップ

`Repro` を `AppDelegate` でインポートし、 `application:didFinishLaunchingWithOptions:` で [セッション](https://docs.repro.io/ja/dev/sdk/session.md) を開始してください。

`YOUR_APP_TOKEN` には管理画面の **設定 > プロジェクト設定 > 認証情報** に記載されている **SDK トークン** を設定してください。

```objc
#import <Repro/Repro.h>

...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    ...

    // Setup Repro
    [Repro setup:@"YOUR_APP_TOKEN"];

    ...
}
```

```swift
import Repro

...

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    ...

    // Setup Repro
    Repro.setup(token: "YOUR_APP_TOKEN")

    // Call the following methods to use Repro's features; they can be called in any desirable place within the app.

    ...
}
```

SDKが収集した情報は定期的にサーバーにアップロードされます。

### イベントをトラックする

意味のある分析や、マーケティング施策を実施するためには、適切なユーザーグループを絞り込むことが重要です。イベントをトラックしてユーザーの行動を記録することにより、管理画面上で目的に応じた適切なユーザーグループを選択することができるようになります。

イベントを用いたユーザーグループ指定の例:

- [キャンペーンの作成画面で、イベントやユーザープロフィールを組み合わせて、配信対象となるユーザーグループを指定する](https://docs.repro.io/ja/dashboard/campaign/target.md)

どういうイベントをとるべきかわからない場合は、まず各画面の表示時にイベントをとってみることをおすすめします。

例:

```objc
@implementation MainViewController

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [Repro track:@"MainViewController" properties:nil];

    ...
}
```

```swift
class MainViewController: UIViewController {

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        Repro.track(event: "MainViewController", properties: [:])

        ...
    }
```

```java
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onResume() {
        super.onResume();
        Repro.track("MainActivity");

        ...
    }
}
```

```kotlin
class MainActivity : AppCompatActivity() {

    override fun onResume() {
        super.onResume()
        Repro.track("MainActivity")

        ...
    }
}
```

```cpp
#include "ReproCpp.h"

...

ReproCpp::track("Initialized");
```

```csharp
Repro.Track ("Initialized");
```

```js-cordova
// Will be written later
```

```js-react-native
class MainScreen extends React.Component {

    componentDidMount() {
        Repro.track("MainScreen", {});
    }

    ...
 }
```

```js-expo
import Repro from 'react-native-repro';

...

Repro.track("MainScreen", {});
```

```dart
import 'package:repro_flutter/repro.dart';

...

await Repro.track("Initialized");
```

### ユーザーIDをセットする

Repro では分析結果はユーザー単位で集計しています。ユーザーIDをセットすることにより、下記のメリットがあります:

- 複数のデバイスを使っているユーザーを同一視できる
- キャンペーンの配信対象の抽出がより精緻になる

詳しくは [こちら](https://docs.repro.io/ja/dev/sdk/user-id.md) をご覧ください。

### プッシュ通知を配信する

Reproでは、管理画面もしくはAPIからプッシュ通知配信をすることができます。プッシュ通知配信をするための実装は [こちら](https://docs.repro.io/ja/dev/sdk/push-notification/index.md) をご覧ください。

### Next...

その他の機能についての詳細は、以下をご覧ください。

- [セッション・ライフサイクル](https://docs.repro.io/ja/dev/sdk/session.md)
- [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md)
- [ユーザーID](https://docs.repro.io/ja/dev/sdk/user-id.md)
- [デバイスID](https://docs.repro.io/ja/dev/sdk/device-id.md)
- [ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md)
- [WebView](https://docs.repro.io/ja/dev/sdk/webview.md)
- [オプトアウト機能](https://docs.repro.io/ja/dev/sdk/optout/index.md)
- [アプリ内メッセージ](https://docs.repro.io/ja/dev/sdk/in-app-message.md)
- [プッシュ通知](https://docs.repro.io/ja/dev/sdk/push-notification/index.md)
- [Adjustで取得したアトリビューションデータをReproにセットする](https://docs.repro.io/ja/dev/sdk/integrate-adjust.md)
- [AppsFlyerで取得したアトリビューションデータをReproにセットする](https://docs.repro.io/ja/dev/sdk/integrate-appsflyer.md)

---

## オプトアウト機能

SDKによるデータ収集とアプリ内メッセージの表示を無効にしたい場合は、オプトアウト機能を利用してください。オプトアウト中のSDKの動作は以下の通りとなります。

- セッションを開始しません
- Reproのサーバにデータを送信しません
- アプリ内メッセージを表示しません

##### NOTE
- オプトアウトの設定はユーザー毎ではなく端末毎の設定です。同一ユーザーが複数端末所持している場合、全ての端末でオプトアウトするには端末毎にオプトアウトの指定が必要です。
- オプトイン中にプッシュ通知のトークンをReproのサーバに送信済みの場合、オプトアウト後もRepro管理画面からプッシュ通知が送信されます。オプトアウト後にプッシュ通知を受信させたくない場合は、端末の設定でプッシュ通知の受信を拒否するよう、エンドユーザーに案内してください。
- ユーザーID、ユーザープロフィール、イベント、プッシュ通知のトークンはオプトイン後にセットしてください。オプトアウト中にセットしても無視されます。



### オプトイン/オプトアウトの指定

`optIn` APIを利用して、オプトイン／オプトアウトを指定できます。引数に `true` を指定するとオプトインとなり、 `false` を指定するとオプトアウトとなります。

```objc
[Repro optIn:NO];
```

```swift
Repro.optIn(endUserOptedIn: false)
```

```java
Repro.optIn(false);
```

```kotlin
Repro.optIn(false)
```

```cpp
ReproCpp::optIn(false);
```

```csharp
Repro.OptIn (false);
```

```js-cordova
Repro.optIn(false);
```

```js-react-native
Repro.optIn(false);
```

```dart
await Repro.optIn(false);
```

##### NOTE
- `optIn` APIで指定した状態は端末内に保存され、次回アプリ起動時にも適用されます。
- オプトアウト状態からオプトイン状態に変更した場合、変更したタイミングでセッションを開始します。

### 初期状態の指定

初期状態はアプリの `Info.plist` (iOS)、および `AndroidManifest.xml` (Android) で指定することが可能です。指定を省略した場合はオプトインが初期状態となります。

* [iOS](https://docs.repro.io/ja/dev/sdk/optout/ios.md)
* [Android](https://docs.repro.io/ja/dev/sdk/optout/android.md)
* [Unity](https://docs.repro.io/ja/dev/sdk/optout/unity.md)
* [Cordova](https://docs.repro.io/ja/dev/sdk/optout/cordova.md)
* [Monaca](https://docs.repro.io/ja/dev/sdk/optout/monaca.md)
* [Cocos2d-x](https://docs.repro.io/ja/dev/sdk/optout/cocos2d-x.md)
* [React Native](https://docs.repro.io/ja/dev/sdk/optout/react-native.md)
* [Flutter](https://docs.repro.io/ja/dev/sdk/optout/flutter.md)

##### NOTE
- [optIn API](#optin-api) を呼び出さない場合、初期状態が適用されます。

---

## オプトイン/オプトアウト初期状態の指定 - iOS

アプリの `Info.plist` を開いてください。



`Add Row` を選択してください。



Keyを `RPREndUserOptInDefault` 、Typeを `Boolean` としてください。Valueを `YES` とするとオプトインが初期状態となります。`NO` とするとオプトアウトが初期状態となります。

---

## オプトイン/オプトアウト初期状態の指定 - Android

アプリの `AndroidManifest.xml` に `meta-data` タグを追加し、 `android:name` を `io.repro.android.EndUserOptInDefault` としてください。 `android:value` を `true` とするとオプトインが初期状態となります。`false` とするとオプトアウトが初期状態となります。

```xml
<meta-data
    android:name="io.repro.android.EndUserOptInDefault"
    android:value="false">
</meta-data>
```

---

## オプトイン/オプトアウト初期状態の指定 - Unity

### iOSプラットフォーム

アプリの `Info.plist` を開いてください。



`Add Row` を選択してください。



Keyを `RPREndUserOptInDefault` 、Typeを `Boolean` としてください。Valueを `YES` とするとオプトインが初期状態となります。`NO` とするとオプトアウトが初期状態となります。



### Androidプラットフォーム

アプリの `AndroidManifest.xml` に `meta-data` タグを追加し、 `android:name` を `io.repro.android.EndUserOptInDefault` としてください。 `android:value` を `true` とするとオプトインが初期状態となります。`false` とするとオプトアウトが初期状態となります。

```xml
<meta-data
    android:name="io.repro.android.EndUserOptInDefault"
    android:value="false">
</meta-data>
```

---

## オプトイン/オプトアウト初期状態の指定 - Cordova

### `config.xml` ファイルを編集する

`config.xml` ファイルの中でオプトイン/オプトアウトの初期状態を指定します。ご利用中のCordovaバージョンによって指定方法が異なります。

#### config-fileタグを使って指定する (Cordova 7.1以上)

##### iOSプラットフォーム

`<platform name="ios">` タグの中に以下を追加してください。 `config-file` タグの中に `<true />` を入れるとオプトインが初期状態となります。 `<false />` を入れるとオプトアウトが初期状態となります。

```xml
<config-file parent="RPREndUserOptInDefault" target="*-Info.plist">
    <false />
</config-file>
```

##### Androidプラットフォーム

`<platform name="android">` タグの中に以下を追加してください。 `meta-data` タグの `android:value` を `true` とするとオプトインが初期状態となります。`false` とするとオプトアウトが初期状態となります。

```xml
<config-file parent="./application" target="AndroidManifest.xml">
    <meta-data android:name="io.repro.android.EndUserOptInDefault" android:value="false">
    </meta-data>
</config-file>
```

#### custom-config-fileタグを使って指定する (Cordova 7.1未満)

Cordova 7.1未満をご利用中の場合、config-fileタグが動作しないため、cordova-custom-configプラグインを利用して指定してください。

cordova-custom-configプラグインが未導入の場合は、以下のように導入してください。

```shell
$ cordova plugin add cordova-custom-config
```

##### iOSプラットフォーム

`<platform name="ios">` タグの中に以下を追加してください。 `custom-config-file` タグの中に `<true />` を入れるとオプトインが初期状態となります。 `<false />` を入れるとオプトアウトが初期状態となります。

```xml
<custom-config-file parent="RPREndUserOptInDefault" target="*-Info.plist">
    <false />
</custom-config-file>
```

##### Androidプラットフォーム

`<platform name="android">` タグの中に以下を追加してください。 `meta-data` タグの `android:value` を `true` とするとオプトインが初期状態となります。`false` とするとオプトアウトが初期状態となります。

```xml
<custom-config-file parent="./application" target="AndroidManifest.xml">
    <meta-data android:name="io.repro.android.EndUserOptInDefault" android:value="false">
    </meta-data>
</custom-config-file>
```

---

## オプトイン/オプトアウト初期状態の指定 - Monaca

### `config.xml` ファイルを編集する

`config.xml` ファイルの中でオプトイン/オプトアウトの初期状態を指定します。ご利用中のCordovaバージョンによって指定方法が異なります。

#### config-fileタグを使って指定する (Cordova 7.1以上)

##### iOSプラットフォーム

`<platform name="ios">` タグの中に以下を追加してください。 `config-file` タグの中に `<true />` を入れるとオプトインが初期状態となります。 `<false />` を入れるとオプトアウトが初期状態となります。

```xml
<config-file parent="RPREndUserOptInDefault" target="*-Info.plist">
    <false />
</config-file>
```

##### Androidプラットフォーム

`<platform name="android">` タグの中に以下を追加してください。 `meta-data` タグの `android:value` を `true` とするとオプトインが初期状態となります。`false` とするとオプトアウトが初期状態となります。

```xml
<config-file parent="./application" target="AndroidManifest.xml">
    <meta-data android:name="io.repro.android.EndUserOptInDefault" android:value="false">
    </meta-data>
</config-file>
```

#### custom-config-fileタグを使って指定する (Cordova 7.1未満)

Cordova 7.1未満をご利用中の場合、config-fileタグが動作しないため、cordova-custom-configプラグインを利用して指定してください。

cordova-custom-configプラグインが未導入の場合は、 [Monacaの公式ドキュメント](https://docs.monaca.io/ja/reference/third_party_phonegap/custom_config/) を参照し、cordova-custom-configを導入してください。

##### iOSプラットフォーム

`<platform name="ios">` タグの中に以下を追加してください。 `custom-config-file` タグの中に `<true />` を入れるとオプトインが初期状態となります。 `<false />` を入れるとオプトアウトが初期状態となります。

```xml
<custom-config-file parent="RPREndUserOptInDefault" target="*-Info.plist">
    <false />
</custom-config-file>
```

##### Androidプラットフォーム

`<platform name="android">` タグの中に以下を追加してください。 `meta-data` タグの `android:value` を `true` とするとオプトインが初期状態となります。`false` とするとオプトアウトが初期状態となります。

```xml
<custom-config-file parent="./application" target="AndroidManifest.xml">
    <meta-data android:name="io.repro.android.EndUserOptInDefault" android:value="false">
    </meta-data>
</custom-config-file>
```

---

## オプトイン/オプトアウト初期状態の指定 - Cocos2d-x

### iOSプラットフォーム

アプリの `Info.plist` を開いてください。



`Add Row` を選択してください。



Keyを `RPREndUserOptInDefault` 、Typeを `Boolean` としてください。Valueを `YES` とするとオプトインが初期状態となります。`NO` とするとオプトアウトが初期状態となります。



### Androidプラットフォーム

アプリの `AndroidManifest.xml` に `meta-data` タグを追加し、 `android:name` を `io.repro.android.EndUserOptInDefault` としてください。 `android:value` を `true` とするとオプトインが初期状態となります。`false` とするとオプトアウトが初期状態となります。

```xml
<meta-data
    android:name="io.repro.android.EndUserOptInDefault"
    android:value="false">
</meta-data>
```

---

## オプトイン/オプトアウト初期状態の指定 - React Native

### iOSプラットフォーム

アプリの `Info.plist` を開いてください。



`Add Row` を選択してください。



Keyを `RPREndUserOptInDefault` 、Typeを `Boolean` としてください。Valueを `YES` とするとオプトインが初期状態となります。`NO` とするとオプトアウトが初期状態となります。



### Androidプラットフォーム

アプリの `AndroidManifest.xml` に `meta-data` タグを追加し、 `android:name` を `io.repro.android.EndUserOptInDefault` としてください。 `android:value` を `true` とするとオプトインが初期状態となります。`false` とするとオプトアウトが初期状態となります。

```xml
<meta-data
    android:name="io.repro.android.EndUserOptInDefault"
    android:value="false">
</meta-data>
```

---

## オプトイン/オプトアウト初期状態の指定 - Flutter

### iOSプラットフォーム

アプリの `Info.plist` を開いてください。



`Add Row` を選択してください。



Keyを `RPREndUserOptInDefault` 、Typeを `Boolean` としてください。Valueを `YES` とするとオプトインが初期状態となります。`NO` とするとオプトアウトが初期状態となります。



### Androidプラットフォーム

アプリの `AndroidManifest.xml` に `meta-data` タグを追加し、 `android:name` を `io.repro.android.EndUserOptInDefault` としてください。 `android:value` を `true` とするとオプトインが初期状態となります。`false` とするとオプトアウトが初期状態となります。

```xml
<meta-data
    android:name="io.repro.android.EndUserOptInDefault"
    android:value="false">
</meta-data>
```

---

## Adjustで取得したアトリビューションデータをReproにセットする

### ユーザープロフィールにセットする

Adjustのアトリビューションデータを [ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md) としてセットできます。

アトリビューションコールバック ([iOS](https://github.com/adjust/ios_sdk#attribution-callback) / [Android](https://github.com/adjust/android_sdk#attribution-callback)) を実装し、取得したデータを [ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md) APIにセットしてください。

```objc
- (void)adjustAttributionChanged:(ADJAttribution *)attribution {
  if (attribution.network != nil) {
    [Repro setStringUserProfile:attribution.network forKey:@"[Adjust]Network"];
  }
  if (attribution.campaign != nil) {
    [Repro setStringUserProfile:attribution.campaign forKey:@"[Adjust]Campaign"];
  }
  if (attribution.adgroup != nil) {
    [Repro setStringUserProfile:attribution.adgroup forKey:@"[Adjust]Adgroup"];
  }
  if (attribution.creative != nil) {
    [Repro setStringUserProfile:attribution.creative forKey:@"[Adjust]Creative"];
  }
}
```

```swift
func adjustAttributionChanged(_ attribution: ADJAttribution!) {
  if attribution.network != nil {
    Repro.setUserProfile(stringValue: attribution.network, forKey: "[Adjust]Network");
  }
  if attribution.campaign != nil {
    Repro.setUserProfile(stringValue: attribution.campaign, forKey: "[Adjust]Campaign");
  }
  if attribution.adgroup != nil {
    Repro.setUserProfile(stringValue: attribution.adgroup, forKey: "[Adjust]Adgroup");
  }
  if attribution.creative != nil {
    Repro.setUserProfile(stringValue: attribution.creative, forKey: "[Adjust]Creative");
  }
}
```

```java
AdjustConfig config = new AdjustConfig(this, appToken, environment);
config.setOnAttributionChangedListener(new OnAttributionChangedListener() {
  @Override
  public void onAttributionChanged(AdjustAttribution attribution) {
    if (attribution.network != null) {
      Repro.setStringUserProfile("[Adjust]Network", attribution.network);
    }
    if (attribution.campaign != null) {
      Repro.setStringUserProfile("[Adjust]Campaign", attribution.campaign);
    }
    if (attribution.adgroup != null) {
      Repro.setStringUserProfile("[Adjust]Adgroup", attribution.adgroup);
    }
    if (attribution.creative != null) {
      Repro.setStringUserProfile("[Adjust]Creative", attribution.creative);
    }
  }
});
```

```kotlin
val config = AdjustConfig(this, appToken, environment)

config.setOnAttributionChangedListener { attribution ->
  if (attribution.network != null) {
    Repro.track("[Adjust]Network", attribution.network)
  }
  if (attribution.campaign != null) {
    Repro.track("[Adjust]Campaign", attribution.campaign)
  }
  if (attribution.adgroup != null) {
    Repro.track("[Adjust]Adgroup", attribution.adgroup)
  }
  if (attribution.creative != null) {
    Repro.track("[Adjust]Creative", attribution.creative)
  }
}
```

### イベントプロパティにセットする

Adjustのアトリビューションデータを [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md) のカスタムイベントのプロパティとしてセットできます。

アトリビューションコールバック ([iOS](https://github.com/adjust/ios_sdk#attribution-callback) / [Android](https://github.com/adjust/android_sdk#attribution-callback)) を実装し、取得したデータを [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md) のカスタムイベントのプロパティとしてセットしてください。

```objc
- (void)adjustAttributionChanged:(ADJAttribution *)attribution {
    [Repro track:@"AdjustAttribution" properties:@{
      @"network":  attribution.network,
      @"campaign": attribution.campaign,
      @"adgroup":  attribution.adgroup,
      @"adid":     attribution.adid
    }];

}
```

```swift
func adjustAttributionChanged(_ attribution: ADJAttribution!) {
  Repro.track(event: "AdjustAttribution", properties:[
    "network":  attribution.network,
    "campaign": attribution.campaign,
    "adgroup":  attribution.adgroup,
    "adid":     attribution.adid
  ])
}
```

```java
AdjustConfig config = new AdjustConfig(this, appToken, environment);
config.setOnAttributionChangedListener(new OnAttributionChangedListener() {
  @Override
  public void onAttributionChanged(AdjustAttribution attribution) {
    Repro.track("AdjustAttribution", new HashMap<String, Object>() {{
      put("network", attribution.network);
      put("campaign", attribution.campaign);
      put("adgroup", attribution.adgroup);
      put("adid", attribution.adgroup);
    }});
  }
});
```

```kotlin
val config = AdjustConfig(this, appToken, environment)
config.setOnAttributionChangedListener { attribution ->
  Repro.track("AdjustAttribution", mapOf(
      "network" to attribution.network,
      "campaign" to attribution.campaign,
      "adgroup" to attribution.adgroup,
      "adid" to attribution.adid
    )
  )
}
```

---

objc, swift, java

## AppsFlyerで取得したアトリビューションデータをReproにセットする

##### WARNING
iOS14.5 以降、App Tracking Transparency(以降ATT)用の実装が必要です、詳細は [こちら](https://support.appsflyer.com/hc/ja/articles/207032066#%E5%AE%9F%E8%A3%85-33-app-tracking-transparency-att%E3%81%AE%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88%E3%81%AE%E5%AE%9F%E8%A3%85) のドキュメントを参照して下さい。

また、iOS14.5 以降、ATTへの同意がない場合基本的にアトリビューションの取得が出来なくなります、詳細は [こちら](https://content.appsflyer.com/ja/ios-14-hub/deep-linking/) のドキュメントを参照して下さい。

カスタムリンクを利用した場合は引き続きアトリビューションを取得し、ユーザープロフィールやイベントプロパティにセットすることが出来ます。

以下のサンプルコードでセットしているアトリビューションのデータはサンプルであり、実際にアプリで取得可能なアトリビューションデータとは異なる場合があります。 Reproにすべてのアトリビューションデータをセットする必要はなく、サンプルコードを参考にキャンペーンや分析に利用するものをセットしてください。

### ユーザープロフィールにセットする

AppsFlyerのアトリビューションデータを [ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md) としてセットできます。

セットしたアトリビューションデータを利用して [広告連動メッセージ](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md#advertisement-linked-message) のようにアトリビューションの内容に合わせてユーザー体験を最適化することが出来ます。

iOS: [onConversionDataSuccess メソッドを実装し](https://support.appsflyer.com/hc/ja/articles/207032066-iOS-SDK-V6-X-%E5%AE%9F%E8%A3%85%E3%82%AC%E3%82%A4%E3%83%89#%E5%AE%9F%E8%A3%85) 、取得したデータをユーザープロフィールとしてセットしてください。

Android: [onConversionDataSuccess メソッドを実装し](https://support.appsflyer.com/hc/ja/articles/207032126-Android-SDK%E3%81%AE%E5%AE%9F%E8%A3%85-%E9%96%8B%E7%99%BA%E8%80%85%E5%90%91%E3%81%91#%E5%AE%9F%E8%A3%85) 、取得したデータをユーザープロフィールとしてセットしてください。

```objc
// AppDelegate.h
#import <UIKit/UIKit.h>
#import <AppsFlyerLib/AppsFlyerLib.h>
#import <AppTrackingTransparency/ATTrackingManager.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate, AppsFlyerLibDelegate> {
 ...
}
@end

// AppDelegate.m
#import "AppDelegate.h"
#import <AppsFlyerLib/AppsFlyerLib.h>
@interface AppDelegate ()
@end
@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // init AppsFlyer
    NSString* appsFlyerDevKey = [properties objectForKey:@"appsFlyerDevKey"];
    NSString* appleAppID = [properties objectForKey:@"appleAppID"];

    [[AppsFlyerLib shared] setAppsFlyerDevKey:appsFlyerDevKey];
    [[AppsFlyerLib shared] setAppleAppID:appleAppID];
    [AppsFlyerLib shared].delegate = self;

    [[AppsFlyerLib shared] start];

    // setup Repro
    [Repro setup:"YOUR_APP_TOKEN"];
}

- (void)onConversionDataSuccess:(NSDictionary*)installData {
    id status = [installData objectForKey:@"af_status"];
    if ([status isEqualToString:@"Non-organic"]) {
        id mediaSource = [installData objectForKey:@"media_source"];
        id campaign = [installData objectForKey:@"campaign"];

        [Repro setStringUserProfile:mediaSource forKey:@"AppsFlyer: media_source"];
        [Repro setStringUserProfile:campaign forKey:@"AppsFlyer: campaign"];

        NSLog(@"This is a none organic install. Media source: %@  Campaign: %@", sourceID, campaign);
    } else if ([status isEqualToString:@"Organic"]) {
        NSLog(@"This is an organic install.");
    }
}

- (void)onConversionDataFail:(NSError *)error {
    NSLog(@"%@",error);
}
```

```swift
func applicationDidBecomeActive(_ application: UIApplication) {
    // init AppsFlyer
    AppsFlyerLib.shared().appsFlyerDevKey = "MY_DEV_KEY"
    AppsFlyerLib.shared().appleAppID = "id123456789"

    // load the conversion data
    AppsFlyerLib.shared().delegate = self

    // track launch
    AppsFlyerLib.shared().start()
}

func onConversionDataSuccess(_ installData: [AnyHashable: Any]) {

    guard let status = installData["af_status"] as? String else {
        return
    }

    if(status == "Non-organic") {
        if let media_source = installData["media_source"] , let campaign = installData["campaign"] {
                Repro.setUserProfile(stringValue: media_source, forKey: "AppsFlyer: media_source")
                Repro.setUserProfile(stringValue: campaign, forKey: "AppsFlyer: campaign")

                print("This is a Non-Organic install. Media source: \(media_source) Campaign: \(campaign) ")
        }
    } else {
        print("This is an organic install.")
    }
}

func onConversionDataFail(_ error: Error!) {
    if let err = error{
    print(err)
}

func onAppOpenAttribution(_ attributionData: [AnyHashable : Any]!) {
    if let data = attributionData{
    print("\(data)")
    }
}

func onAppOpenAttributionFailure(_ error: Error!) {
    if let err = error{
    print(err)
    }
}
```

```java
AppsFlyerConversionListener conversionListener = new AppsFlyerConversionListener() {
    @Override
    public void onConversionDataSuccess(Map<String, String> conversionData) {
        for (String attrName : conversionData.keySet()) {
          String attrValue = conversionData.get(attrName);
            Log.d(AppsFlyerLib.LOG_TAG, "attribute: " + attrName + " = " + attrValue);
            if (attrName.equals("media_source")) {
                Repro.setStringUserProfile("AppsFlyer: media_source", attrValue);
            }
            else if (attrName.equals("campaign")) {
                Repro.setStringUserProfile("AppsFlyer: campaign", attrValue);
            }
        }
    }

    @Override
    public void onConversionFail(String errorMessage) {
        Log.d(AppsFlyerLib.LOG_TAG, "error getting conversion data: " + errorMessage);
    }

    @Override
    public void onAppOpenAttribution(Map<String, String> conversionData) {
    }

    @Override
    public void onAttributionFailure(String errorMessage) {
        Log.d(AppsFlyerLib.LOG_TAG, "error onAttributionFailure : " + errorMessage);
    }
});
```

##### WARNING
- このコールバックはアプリのインストール時のみ呼ばれます。
- AppsFlyerの初期化より先に、Reproのsetupを実行してください。

### イベントプロパティにセットする

AppsFlyerのアトリビューションデータを [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md) のカスタムイベントのプロパティとしてセットできます。

セットしたアトリビューションデータを利用して [広告連動メッセージ](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md#advertisement-linked-message) のようにアトリビューションの内容に合わせてユーザー体験を最適化することが出来ます。

iOS: [onConversionDataSuccess メソッドを実装し](https://support.appsflyer.com/hc/ja/articles/207032066-iOS-SDK-V6-X-%E5%AE%9F%E8%A3%85%E3%82%AC%E3%82%A4%E3%83%89#%E5%AE%9F%E8%A3%85) 、取得したデータを [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md) のカスタムイベントのプロパティとしてセットしてください。

Android: [onConversionDataSuccess メソッドを実装し](https://support.appsflyer.com/hc/ja/articles/207032126-Android-SDK%E3%81%AE%E5%AE%9F%E8%A3%85-%E9%96%8B%E7%99%BA%E8%80%85%E5%90%91%E3%81%91#%E5%AE%9F%E8%A3%85) 、取得したデータを [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md) のカスタムイベントのプロパティとしてセットしてください。

```objc
// AppDelegate.h
#import "AppsFlyerTracker.h"

@interface AppDelegate : UIResponder<UIApplicationDelegate, AppsFlyerTrackerDelegate> {

    ...

}

// AppDelegate.m

- (void)applicationDidBecomeActive:(UIApplication *)application {
    // setup Repro
    [Repro setup:"YOUR_APP_TOKEN"];

    // init AppsFlyer
    [[AppsFlyerLib shared] setAppsFlyerDevKey:@"MY_DEV_KEY"];
    [[AppsFlyerLib shared] setAppleAppID:@"id123456789"];

    // load the conversion data
    [AppsFlyerLib shared].delegate = self;
    // track launch
    [[AppsFlyerLib shared] start];
}

- (void)onConversionDataSuccess:(NSDictionary*)installData {
    id status = [installData objectForKey:@"af_status"];
    if ([status isEqualToString:@"Non-organic"]) {
        id mediaSource = [installData objectForKey:@"media_source"];
        id campaign = [installData objectForKey:@"campaign"];
        id adset = [installData objectForKey:@"af_adset"];
        id ad = [installData objectForKey:@"af_ad"];
        [Repro track:@"AppsFlyerAttribution" properties:@{
            @"mediaSource": mediaSource,
            @"campaign": campaign,
            @"adset": adset,
            @"ad": ad,
        }];

        NSLog(@"This is a none organic install. Media source: %@  Campaign: %@", sourceID, campaign);
    } else if ([status isEqualToString:@"Organic"]) {
        NSLog(@"This is an organic install.");
    }
}

- (void)onConversionDataFail:(NSError *)error {
    NSLog(@"%@",error);
}
```

```swift
func applicationDidBecomeActive(_ application: UIApplication) {
    // init AppsFlyer
    AppsFlyerLib.shared().appsFlyerDevKey = "MY_DEV_KEY"
    AppsFlyerLib.shared().appleAppID = "id123456789"

    // load the conversion data
    AppsFlyerLib.shared().delegate = self
    // track launch
    AppsFlyerLib.shared().start()
}

func onConversionDataSuccess(_ installData: [AnyHashable: Any]) {

    guard let status = installData["af_status"] as? String else {
        return
    }

    if(status == "Non-organic") {
        if let mediaSource = installData["media_source"], let campaign = installData["campaign"], let adset = installData["af_adset"], let ad = installData["af_ad"] {
            Repro.track(
                event: "AppsFlyerAttribution",
                properties: [
                    "mediaSource": mediaSource,
                    "campaign": campaign,
                    "adset": adset,
                    "ad": ad
                ])
        }
    } else {
        print("This is an organic install.")
    }
}

func onConversionDataFail(_ error: Error!) {
    if let err = error{
    print(err)
}
```

```java
AppsFlyerConversionListener conversionListener = new AppsFlyerConversionListener() {
    @Override
    public void onConversionDataSuccess(Map<String, Object> conversionData) {
        final Object afStatus = conversionData.get("af_status");
        if (afStatus instanceof String && afStatus.equals("Non-organic")) {
            Map<String, Object> map = new HashMap<String, Object>();
            for (String attrName : conversionData.keySet()) {
                Object attrValue = conversionData.get(attrName);
                Log.d(AF_TAG, "attribute: " + attrName + " = " + attrValue);
                if (attrName.equals("network")) {
                    map.put("network", attrValue);
                }
                else if (attrName.equals("campaign")) {
                    map.put("campaign", attrValue);
                }
                else if (attrName.equals("af_adset")) {
                    map.put("adset", attrValue);
                }
                else if (attrName.equals("af_ad")) {
                    map.put("ad", attrValue);
                }
            }
            Repro.track("AppsFlyerAttribution", map);
        }
    }

    @Override
    public void onConversionFail(String errorMessage) {
        Log.d(AppsFlyerLib.LOG_TAG, "error getting conversion data: " + errorMessage);
    }
});
```

##### WARNING
- このコールバックはアプリのインストール時のみ呼ばれます。
- AppsFlyerの初期化より先に、Reproのsetupを実行してください。

---

## QRコードを用いてオーディエンスにユーザーを登録する

##### WARNING
本機能を利用するためには Android SDK 5.15.0 以上 および iOS SDK 5.16.0 以上 を利用する必要があります。

### Android

QRコードを用いてオーディエンスを登録するためには、アプリの `AndroidManifest.xml` ファイルに以下の設定を追加してください。

```xml
<manifest>
    <application>
        ...
        <activity
            android:name="io.repro.android.DeepLinkHandler"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.VIEW"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="android.intent.category.BROWSABLE"/>

                <data android:scheme="rpr-{YOUR_PROJECT_ID}"/>
            </intent-filter>
        </activity>
        ...
    </application>
</manifest>
```

`{YOUR_PROJECT_ID}` の箇所には、使用しているプロジェクトのIDを指定してください。
プロジェクトIDは管理画面の **設定 > プロジェクト設定 > 全般** から確認をすることができます。



### iOS

QRコードを用いてオーディエンスを登録するためには、アプリの `Info.plist` ファイルに以下の設定を追加してください。

```xml
<dict>
    ...
    <key>CFBundleURLTypes</key>
    <array>
        ...
        <dict>
            <key>CFBundleURLSchemes</key>
            <array>
                ...
                <string>rpr-{YOUR_PROJECT_ID}</string>
            </array>
        </dict>
    </array>
</dict>
```

`{YOUR_PROJECT_ID}` の箇所には、使用しているプロジェクトのIDを指定してください。
プロジェクトIDは管理画面の **設定 > プロジェクト設定 > 全般** から確認をすることができます。

---

## 広告ID取得設定

### Android

#### 広告IDの取得を有効にする

広告ID (AAID) はデフォルトでは取得およびReproへの送信がされません。
取得および送信を行うためには、アプリの `AndroidManifest.xml` ファイルに以下の設定を追加してください。

```xml
  <manifest>
      <application>
          <meta-data
              android:name="io.repro.android.AAIDCollectionEnabled"
              android:value="true">
          </meta-data>
          ...
      </application>
  </manifest>
```

##### NOTE
Repro Android SDK 5.13.0未満のバージョンではデフォルトで広告IDが取得・送信されます。
またRepro Android SDK 5.8.0未満では本機能を利用できず、常に広告IDが取得・送信されます。

#### 許可の追加

Android 13 以上をターゲットにする場合、以下のようにマニフェストファイルで `com.google.android.gms.permission.AD_ID` の権限を宣言してください。

```xml
  <manifest xmlns:android="http://schemas.android.com/apk/res/android">
      <uses-permission android:name="android.permission.INTERNET" />
      <uses-permission android:name="com.google.android.gms.permission.AD_ID"/>
          ...
      </application>
  </manifest>
```

#### 依存ライブラリの追加

最後に、広告IDを取得するために必要なライブラリへの依存関係を `app/build.gradle` ファイルに追加してください。

```groovy
  dependencies {
      ...other dependencies...
      implementation 'io.repro:repro-android-sdk:...'

      implementation 'com.google.android.gms:play-services-ads-identifier:18.2.0'
  }
```

##### NOTE
もし既にアプリで `com.google.android.gms:play-services-ads` ライブラリを使用している場合、 `com.google.android.gms:play-services-ads-identifier` を利用するための設定は必要ありません。

### iOS

広告ID (IDFA) はデフォルトでは取得およびReproへの送信がされません。
取得および送信を行うためには、アプリの `Info.plist` ファイルに以下の設定を追加してください。

```xml
<dict>
    <key>RPRIDFACollectionEnabled</key>
    <true/>
    ...
</dict>
```

##### NOTE
Repro Android SDK 5.14.0未満のバージョンでは本機能は利用できず、常に広告IDが取得・送信されます。

---

## iOS SDK 4.0.3 Swift版API 変更一覧

iOS版の Repro SDK 4.0.3 にて、Swift用APIのメソッド名およびシグニチャーが変更されました。
変更されたメソッドは下記の通りです。変更後のAPIの使用方法については開発ガイドを参照してください。

| 変更前, 変更後 |  |
| --- | --- |
| `Repro.optIn(true)` | `Repro.optIn(endUserOptedIn: true)` |
| `Repro.setup("YOUR_APP_TOKEN")` | `Repro.setup(token:"YOUR_APP_TOKEN")` |
| `Repro.setUserID("user_id")` | `Repro.set(userID: "user_id")` |
| `Repro.getUserID()` | `Repro.userID()` |
| `Repro.getDeviceID()` | `Repro.deviceID()` |
| `Repro.setStringUserProfile("green", forKey: "eyecolor")` | `Repro.setUserProfile(stringValue: "green", forKey: "eyecolor")` |
| `Repro.setIntUserProfile(30, forKey: "age")` | `Repro.setUserProfile(integerValue: 30, forKey: "age")` |
| `Repro.setDoubleUserProfile(40.5, forKey: "shoesize")` | `Repro.setUserProfile(doubleValue: 40.5, forKey: "shoesize")` |
| `Repro.setDateUserProfile(NSDate() as Date, forKey: "now")` | `Repro.setUserProfile(dateValue: Date(), forKey: "now")` |
| `Repro.setUserGender(.male)` | `Repro.setUserProfile(gender: .male)` |
| `Repro.setUserEmailAddress("user@example.com")` | `Repro.setUserProfile(emailAddress: "user@example.com")` |
| `Repro.track("trackname", properties: [:])` | `Repro.track(event: "trackname", properties: [:])` |
| `Repro.startWebViewTracking(self)` | `Repro.startWebViewTracking(delegate: self)` |
| `Repro.trackViewContent("contentIDstr", properties: nil)` | `Repro.trackViewContentEvent(contentID: "contentIDstr", properties: nil)` |
| `Repro.trackSearch(nil)` | `Repro.trackSearchEvent(properties: nil)` |
| `Repro.trackAdd(toCart: "contentIDstr", properties: nil)` | `Repro.trackAddToCartEvent(contentID: "contentIDstr", properties: nil)` |
| `Repro.trackAdd(toWishlist: nil)` | `Repro.trackAddToWishlistEvent(properties: nil)` |
| `Repro.trackInitiateCheckout(nil)` | `Repro.trackInitiateCheckoutEvent(properties: nil)` |
| `Repro.trackAddPaymentInfo(nil)` | `Repro.trackAddPaymentInfoEvent(properties: nil)` |
| `Repro.trackPurchase("contentIDstr", value: 3.50, currency: "USD", properties: nil)` | `Repro.trackPurchaseEvent(contentID: "contentIDstr", value: 3.50, currency: "USD", properties: nil)` |
| `Repro.trackShare(nil)` | `Repro.trackShareEvent(properties: nil)` |
| `Repro.trackCompleteRegistration(nil)` | `Repro.trackCompleteRegistrationEvent(properties: nil)` |
| `Repro.trackLead(nil)` | `Repro.trackLeadEvent(properties: nil)` |
| `Repro.setLogLevel(.debug)` | `Repro.set(logLevel: .debug)` |
| `Repro.setPushDeviceToken(NSData() as Data)` | `Repro.setPushDeviceToken(data: Data())` |
| `Repro.setPushDeviceTokenString("03df25c...")` | `Repro.setPushDeviceToken(string: "03df25c...")` |
| `Repro.disableInAppMessageOnActive()` | `Repro.disableInAppMessageOnActive()` |
| `Repro.showInAppMessage()` | `Repro.showInAppMessage()` |

---

## ドメイン移行に伴う作業

2017年9月頃に世界中で発生した `.io` ドメインの名前解決に失敗する問題を鑑み、より信頼性の高い `.com` (gTLD) ドメインを利用するようシステム改修を行いました。古いドメインも継続してご利用になれますが新ドメインへの移行を推奨しております。新ドメインをご利用いただくには以下の手順に従ってください。

<!-- SDKの通信先ドメイン、WebView用JavaScriptライブラリのダウンロードURL、プッシュAPIのエンドポイント、およびユーザープロフィールAPIのエンドポイントのドメインを、 ``repro.io`` から ``reproio.com`` に移行しました。 -->

* [SDKのアップグレード](https://docs.repro.io/ja/releases/change-domain/sdk/index.md)
* [WebView用JavaScriptライブラリダウンロードURLの変更](https://docs.repro.io/ja/releases/change-domain/webview.md)
* [プッシュAPIエンドポイントの変更](https://docs.repro.io/ja/releases/change-domain/push-api.md)
* [ユーザープロフィールAPIエンドポイントの変更](https://docs.repro.io/ja/releases/change-domain/user-profile-api.md)

##### NOTE
Reproの管理画面へは引き続き `https://app.repro.io` でアクセス可能です。

---

## SDKのアップグレード

### 最新版を利用する

2018年2月20日にリリースした以下のバージョン以降は新しいドメイン `reproio.com` に接続しますので、2018年2月20日以降の最新版をご利用ください。

- [iOS SDK 2.9.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-2-9-1)
- [Android SDK 2.10.1](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-2-10-1)
- [Unity Package 3.5.1](https://docs.repro.io/ja/releases/sdk/unity/releases.md#unity-3-5-1)
- [Cordova Plugin 3.6.2](https://docs.repro.io/ja/releases/sdk/cordova/releases.md#cordova-3-6-2)
- [Cocos2d-x SDK 2.0.1](https://docs.repro.io/ja/releases/sdk/cocos2d-x/releases.md#cocos2d-x-2-0-1)

最新版SDKへの更新手順は以下のページをご覧ください。

- [iOS](https://docs.repro.io/ja/releases/sdk/ios/upgrade.md)
- [Android](https://docs.repro.io/ja/releases/sdk/android/upgrade.md)
- [Unity](https://docs.repro.io/ja/releases/sdk/unity/upgrade.md)
- [Cordova](https://docs.repro.io/ja/releases/sdk/cordova/upgrade.md)
- [Cocos2d-x](https://docs.repro.io/ja/releases/sdk/cocos2d-x/upgrade.md)

### バックポート版を利用する

2018年2月20日時点でサポートしているSDKのすべてのマイナーバージョンごとに、通信先のドメインのみを変更したバックポート版をリリースしました。最新版へのアップグレードが難しい場合は、以下の手順に従いバックポート版をご利用いただくことも可能です。

* [iOS](https://docs.repro.io/ja/releases/change-domain/sdk/ios.md)
* [Android](https://docs.repro.io/ja/releases/change-domain/sdk/android.md)
* [Unity](https://docs.repro.io/ja/releases/change-domain/sdk/unity.md)
* [Cordova](https://docs.repro.io/ja/releases/change-domain/sdk/cordova.md)
* [Monaca](https://docs.repro.io/ja/releases/change-domain/sdk/monaca.md)
* [Cocos2d-x](https://docs.repro.io/ja/releases/change-domain/sdk/cocos2d-x.md)

---

java

## Android SDK リリースノート

* [Android SDK 更新手順](https://docs.repro.io/ja/releases/sdk/android/upgrade.md)



##### WARNING
- [Android SDK 5.13.0](#android-5-13-0) より、広告IDを取得するためには別途設定が必要になります。
- [Android SDK 5.22.0](#android-5-22-0) より、AndroidXを有効にする必要があります。Gradleの設定に `android.useAndroidX=true` を設定してください。



### 5.24.0 (2026/06/08)

変更

- アプリ内メッセージが表示された状態でActivityが変更された場合、表示されているアプリ内メッセージが最上位のActivityに移動するようになりました。

修正

- Activityを連続で遷移した場合にアプリ内メッセージが消える問題を修正しました。
- プッシュ通知を経由してブラウザを開き、アプリに戻った場合に再度ブラウザが開いてしまう不具合を修正しました。



### 5.23.0 (2026/04/24)

変更

- 内部用のAPIを追加しました。

修正

- 一部のイベントにおいて、プロパティに特定の文字列が含まれる場合にクラッシュが発生する可能性がある問題を修正しました。



### 5.22.0 (2026/04/01)

修正

- エッジ ツー エッジをサポートしました。
- 軽微な不具合を修正しました。

##### WARNING
このバージョンより、AndroidXを有効にする必要があります。Gradleの設定に `android.useAndroidX=true` を設定してください。



### 5.21.0 (2026/03/05)

新機能

- アプリ内メッセージを表示する際の表示優先度を設定できるようになりました。
  - 詳細は [アプリ内メッセージの表示優先度を調整する](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md#in-app-message-delivery) を参照してください。



### 5.20.9 (2026/02/13)

修正

- compileSdkVersion/targetSdkVersionを35に変更しました。



### 5.20.8 (2026/01/30)

修正

- アプリケーションコンテキストを渡さない非推奨のセットアップメソッドが削除されました。
- ログ関連のストレージI/Oを低減させ、パフォーマンスを向上させました。
- まれに発生していた、バックグラウンドからフォアグラウンドへの素早い遷移時に新しいセッションが開始されない問題を修正しました。



### 5.20.7 (2026/01/27)

修正

- ユーザープロフィールのセットで発火するトリガーをセット操作のみに修正しました。詳細は [ユーザープロフィールのセットによってトリガーを実行する](https://docs.repro.io/ja/dashboard/campaign/in-app-message.html#id25) を参照してください。



### 5.20.6 (2026/01/07)

変更

- ストレージのI/Oを低減することで、パフォーマンスの向上と消費電力の削減を実現しました。



### 5.20.5 (2025/12/19)

修正

軽微な不具合を修正しました。



### 5.20.4 (2025/11/18)

修正

軽微な不具合を修正しました。



### 5.20.3 (2025/11/14)

修正

軽微な不具合を修正しました。

##### WARNING
特定の場合においてHTMLアプリ内メッセージを表示する際にクラッシュする可能性があるため、このバージョンのご利用は推奨しません。

代わりに、 [Android SDK 5.20.4](#android-5-20-4) 以降のバージョンをご利用ください。



### 5.20.2 (2025/10/23)

修正

軽微な不具合を修正しました。

##### WARNING
特定の場合においてHTMLアプリ内メッセージを表示する際にクラッシュする可能性があるため、このバージョンのご利用は推奨しません。

代わりに、 [Android SDK 5.20.4](#android-5-20-4) 以降のバージョンをご利用ください。



### 5.20.1 (2025/09/29)

修正

軽微な不具合を修正しました。



### 5.20.0 (2025/07/28)

新機能

- ユーザープロフィールの設定方法として、条件付きセット操作、増減操作、削除の操作が追加されました。
  - 詳細は [ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md) を参照してください。

変更

- WebViewでReproを利用するためのライブラリ `repro.js` のバージョン8がリリースされました。
  - 詳細は [Webページにトラッキングコードを追加する](/ja/dev/sdk/webview.html#web) を参照してください。



### 5.19.0 (2025/04/25)

修正

軽微な不具合を修正しました。



### 5.18.1 (2025/04/07)

変更

React NativeおよびFlutter向けプラグインの機能改善に向け、内部処理を修正しました。



### 5.18.0 (2024/12/26)

新機能

- HTMLアプリ内メッセージにおいて、オリジナルテンプレート(ID1000)でメッセージを作成する際、メッセージ内で任意のイベントのトラッキングやユーザープロフィールの設定を行うことができるようになりました。
  - 詳細は [HTMLアプリ内メッセージでイベントトラッキングおよびユーザープロフィールの設定を行う](https://docs.repro.io/ja/dashboard/campaign/html-in-app-message.md#html-inapp-tracking) 、 [ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md) および [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md) を参照してください
- HTMLアプリ内メッセージにおいて、オリジナルテンプレート(ID1000)でメッセージを作成する際、メッセージ内でアプリ内メッセージの表示トリガーとなったイベントのプロパティを取得できるようになりました。
  - 詳細は [HTMLアプリ内メッセージでイベントプロパティの取得を行う](https://docs.repro.io/ja/dashboard/campaign/html-in-app-message.md#html-inapp-triggered-properties) を参照してください。
- WebViewを利用してWebページを表示する際、ページ内でユーザープロフィールの設定を行うことができるようになりました。
  - 詳細は [WebView](https://docs.repro.io/ja/dev/sdk/webview.md) および [ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md) を参照してください。

変更

- WebViewでReproを利用するためのライブラリ `repro.js` のバージョン6がリリースされました。
  - 詳細は [Webページにトラッキングコードを追加する](/ja/dev/sdk/webview.html#web) を参照してください。

##### WARNING
- WebViewにおいてユーザープロフィールの設定を行う場合は、バージョン6の `repro.js` を利用する必要があります。



### 5.17.1 (2024/10/30)

修正

- HTMLアプリ内メッセージにおいてメッセージ情報の取得時のタイムアウト時間を変更しました。



### 5.17.0 (2024/10/03)

修正

- データ収集における信頼性向上のための軽微な修正を行いました。



### 5.16.0 (2024/07/10)

新機能

- 「ニュースフィード」機能で取得できるパラメータに `linkUrlString` `imageUrlString` を追加しました。
  - パラメータの追加に伴い、 `linkUrl` `imageUrl` は非推奨になりました。
  - 詳細は [ニュースフィード](https://docs.repro.io/ja/dev/sdk/newsfeed.html)  を参照してください。

修正

- 特定の状態においてプッシュ通知に設定したディープリンクが正常に動作しない場合がある問題を修正しました。



### 5.15.0 (2024/05/17)

新機能

- QRコードを用いてオーディエンスにユーザーを登録する機能を追加しました。
  - 詳細は [QRコードを用いてオーディエンスにユーザーを登録する](https://docs.repro.io/ja/dev/sdk/qr-code.md#qr-code) を参照してください。



### 5.14.0 (2024/04/30)

新機能

- 標準ユーザープロフィールとして登録可能な項目を追加しました。
  - 詳細は [標準ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md#standard-user-profile) を参照してください。



### 5.13.0 (2024/01/19)

変更

- 広告IDをデフォルトで取得しないよう変更しました。
  - 広告IDを取得する方法については [広告ID取得設定](https://docs.repro.io/ja/dev/sdk/ad-id.md#ad-id) を参照してください。



### 5.12.0 (2023/11/17)

修正

- ディープリンクを設定したプッシュ通知を連続してタップしたとき、特定の場合において2度目以降にタップされた通知に設定されたディープリンクが動作しない問題を修正しました。
- アプリ内メッセージの配信対象のユーザーがコントロールグループに割り当てられたとき、そのメッセージの表示に必要なのトリガーを短時間に複数回実行すると表示回数が不正にカウントされる問題を修正しました。
- Repro Android SDKが他社製のSDKと競合しSDKの導入ができない場合がある問題を修正しました。



### 5.11.0 (2023/10/16)

変更

- アプリ内メッセージにおいて、これを閉じたことを内部的に記録する条件を一部変更しました。
  - 例えばバナータイプのアプリ内メッセージが時間経過で自動的に消える場合など、ユーザーが意図してメッセージを閉じる操作を行わない場合は記録を行わないようになります。
- SDKが内部で使用しているActivityに対する `intent-filter` の指定を削除しました。



### 5.10.0 (2023/09/12)

変更

- AndroidにおけるOSの最低サポートバージョンがAndroid 5.0(API 21)に変更されました。
  - Android SDK 5.10.0以降ではAndroid 5.0未満を動作対象とするアプリにはSDKを導入することができません。
  - またAndroid SDK 5.10.0未満を利用する場合はAndroid 5.0未満を動作対象とするアプリにSDKを導入することはできますが、Android 5.0未満の端末ではReproの機能を利用することができないためご注意ください。



### 5.9.0 (2023/06/12)

変更

- SDKがサーバーと通信をする際のデータ量を削減する対応を行いました。



### 5.8.0 (2023/03/08)

新機能

- Google Playのファミリーポリシーの要件等に従うため、AAIDの取得を無効化する機能を追加しました。
  - 詳細は [広告IDを取得しないようにする](https://docs.repro.io/ja/dev/sdk/ad-id.md#ad-id) をご覧ください。



### 5.7.2 (2022/12/27)

修正

- シルバーエッグレコメンドメッセージの利用時、サーバーに対し誤ったパラメータを送信している問題を修正しました。



### 5.7.1 (2022/10/05)

変更

- 内部仕様の変更により、不要となった情報をサーバーに送信しないよう変更しました。



### 5.7.0 (2022/07/22)

新機能

- ユニバーサルリンク･アプリリンクに対応するためのコールバック処理の記述が可能になりました。
  - 詳細は [オプション：アプリリンクを使用する](https://docs.repro.io/ja/dev/sdk/push-notification/android.md#android-app-link-guide) をご覧ください。



### 5.6.3 (2022/04/11)

修正

- Repro SDKのAPIに誤ったパラメータを指定した際の検知機能を強化しました。



### 5.6.2 (2022/02/16)

修正

- ログレベルのデフォルト値が正しくない問題を修正しました。
  - [ログレベル](https://docs.repro.io/ja/dev/sdk/log.md) に掲載の通り、 `Info` レベルがデフォルトの動作となります。
- ログ情報の出力時にANRが発生する可能性がある問題を修正しました。



### 5.6.1 (2022/01/25)

新機能

- 特定のアクティビティの起動時にReproとのセッションの開始を抑制する方法を追加しました。
  - 詳細は [こちら](https://docs.repro.io/ja/dev/sdk/push-notification/android.md) をご覧ください。



### 5.6.0 (2021/12/06)

新機能

- 「ニュースフィード」機能を用いて、プッシュ通知に加え アプリ内メッセージおよび Webメッセージ の履歴を取得できるようになりました。
  - 詳細は [こちら](https://docs.repro.io/ja/dev/sdk/newsfeed.md) をご覧ください。



### 5.5.1 (2021/07/30)

修正

- アプリケーションでFirebase Cloud Messaging バージョン 22.0.0以上を使用している際に、プッシュ通知を受信できない場合がある問題を修正しました。



### 5.5.0 (2021/07/20)

新機能

- アプリ起動中も一定期間ごとにアプリ内メッセージの取得が行われるようになります。

変更

- これまで1セッション中に同じメッセージは1度しか表示されない仕様でしたが、今回のアップデートにより、セッション中に同じメッセージが複数回表示されるようになります。

修正

- `targetSdkVersion 31` を指定してビルドしたアプリで、スタンダード形式のプッシュ通知をタップしても、アプリ起動できない問題を修正しました。



### 5.4.1 (2021/06/16)

修正

- ANRのクラッシュレポートに誤ってReproの情報が記載されることを防ぐため、Repro SDKから内部のAndroid Serviceを削除しました。



### 5.4.0 (2021/05/20)

新機能

- HTMLアプリ内メッセージの一部のテンプレートにて記述されたJavaScriptを利用できるようになりました。



### 5.3.0 (2021/03/08)

修正

- HTMLアプリ内メッセージを表示中にバックキーを連打すると再表示されてしまう問題を修正しました。
- 軽微な不具合を修正しました。



### 5.2.0 (2021/02/01)

変更

- ユーザープロフィールおよびイベント名の先頭・末尾にスペースが含まれている場合、これを無視するよう変更しました。
- シルバーエッグレコメンドメッセージにおける内部処理を変更しました。

修正

- 通信処理における軽微な不具合を修正しました。



### 5.1.12 (2021/01/19)

修正

- イベントデータアップロードにおける軽微な不具合を修正しました。



### 5.1.9 (2020/12/23)

修正

- HTMLアプリ内メッセージの表示中に Android のバックキーをタップしたとき、アプリが終了される場合がある問題を修正しました。



### 5.1.7 (2020/12/17)

修正

- コントロールグループ表示後、特定の条件下でアプリ内メッセージが表示されない問題を修正しました。
- HTMLアプリ内メッセージでボタンが複数回クリックできてしまう問題を修正しました。
- アプリ内メッセージの表示中に新たなメッセージを表示しようとした際の問題を修正しました。



### 5.1.4 (2020/11/18)

修正

- 特定の条件下でアプリ内メッセージが表示されない問題を修正しました。



### 5.1.3 (2020/10/22)

修正

- `enableInAppMessagesOnForegroundTransition` を1プロセス内で複数回呼び出したときの挙動を変更しました。



### 5.1.2 (2020/10/19)

修正

- アプリをバックグラウンドに切り替えると、稀にクラッシュする不具合を修正しました。



### 5.1.0 (2020/08/11)

修正

- Android Manifestにて `targetSdkVersion 30` を指定したアプリにて、セッションが開始されない問題を修正しました。
- デバイスのネットワーク接続が悪い場合の改善をしました。
- Firebase SDK と一緒にリンクされたアプリの安定性を改善しました。



### 5.0.4 (2020/08/04)

修正

- サーバとの通信が不正な状態になった場合に、稀にクラッシュする不具合を修正しました。



### 5.0.3 (2020/07/01)

修正

- イベントデータアップロードにおける軽微な不具合を修正しました。



### 5.0.2 (2020/06/27)

修正

- アプリをバックグラウンドに切り替えると、稀にセッションデータのアップロードに失敗する不具合を修正しました。
- サーバとの通信がエラーになった場合に、稀にクラッシュする不具合を修正しました。



### 5.0.1 (2020/06/24)

修正

- ニュースフィードのデータを正しくない形式で利用できてしまう不具合を修正しました。



### 5.0.0 (2020/06/19)

新機能

- アプリがフォアグラウンド中にイベントやユーザープロフィールなどの情報が定期的にアップロードされるようになり、データの処理タイミングが早くなりました。

変更

- アプリ内メッセージ機能に関する以下のAPIの名称を変更しました。
  - `disableInAppMessageOnActive` → `disableInAppMessagesOnForegroundTransition`
- 以下のAPIを削除しました。
  - `showInAppMessage`
- 以下のAPIを追加しました。
  - `enableInAppMessagesOnForegroundTransition`

##### WARNING
今回のバージョンは修正範囲が広いため、一度v5.0.0を組み込んでリリースした後に、ダウングレードしてアプリをリリースすると不具合が発生する可能性がございます。ダウングレードは推奨いたしませんのでご注意ください。



### 4.5.0 (2020/05/20)

新機能

- プッシュ通知の機能に「ニュースフィード」の機能を追加しました。



### 4.4.1 (2020/04/08)

変更

- 「HTMLアプリ内メッセージ」機能の正式リリースに伴い、パフォーマンスを改善しました。



### 4.4.0 (2020/03/23)

新機能

- Reproのキャンペーン表示を、ユーザーの行動とリアルタイムで連動して行うことができるようになりました。
  - 詳細は [メッセージ表示トリガー](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md#in-app-message-trigger) をご覧ください。

修正

- TabActivity を使用した際に、誤った形式のセッションデータがアップロードされる問題を修正しました。



### 4.3.1 (2020/01/22)

修正

- 「AIレコメンド・アプリ内メッセージ連携機能（クローズドβ）」における軽微な不具合を修正しました。



### 4.3.0 (2019/12/10)

新機能

- アプリ内メッセージ機能に「AIレコメンド・アプリ内メッセージ連携機能（クローズドβ）」を追加しました。



### 4.2.1 (2019/10/24)

修正

- 特定の文字がユーザーIDに含まれると、ユーザープロフィールが設定されない不具合を修正しました。



### 4.2.0 (2019/10/07)

新機能

- メッセージ内容を HTML と CSS でカスタマイズできる「HTMLアプリ内メッセージ（クローズドβ）」機能を追加しました。



### 4.1.0 (2019/08/30)

新機能

- UXオプティマイザー機能（クローズドβ）を追加しました。



### 4.0.6 (2019/07/19)

修正

- プッシュ通知を開封した際、稀にセッションの開始に失敗する不具合を修正しました。



### 4.0.4 (2019/05/22)

修正

- アプリ内メッセージのダイアログに、アプリケーションの独自テーマが適用される問題を修正しました。

変更

- 動画機能に関する以下のAPIを削除しました。
  - `startRecording`
  - `stopRecording`
  - `pauseRecording`
  - `resumeRecording`
  - `mask`
  - `unmask`



### 3.3.1 (2019/04/19)

変更

- 日本国外の一部のアプリにおいて、アプリ内メッセージの画像ダウンロードのタイムアウト時間を調整しました。



### 3.3.0 (2019/02/14)

変更

- 動画機能に関する主要なコードを削除し、動画機能が動作しないようにしました。以下のAPIを呼び出しても問題ありませんが何も実行されません。
  - `startRecording`
  - `stopRecording`
  - `pauseRecording`
  - `resumeRecording`
  - `mask`
  - `unmask`

  #### WARNING
  録画関連APIは削除されました。2019年5月22日現在、これを利用することはできません。

修正

- アプリ内メッセージを表示中に画面遷移した場合、その後トリガーイベントが発生してもアプリ内メッセージが表示されない不具合を修正しました。
- ダイアログタイプとオーバーレイタイプのアプリ内メッセージのレイアウトが稀に崩れる不具合を修正しました。



### 3.2.0 (2019/01/30)

新機能

- オプトアウト機能を追加しました。
  - オプトアウト機能を利用することで、SDKによるデータ収集とアプリ内メッセージの表示を無効にできます。詳細は [こちら](https://docs.repro.io/ja/dev/sdk/optout/index.md) をご覧ください。



### 3.1.6 (2019/01/08)

修正

- 一部のデバイスにおいてアプリ内メッセージを表示する時に稀にクラッシュするバグを修正しました。



### 3.1.1 (2018/11/14)

変更

- GCMのサポートを廃止しました。
  - GCMをご利用中の場合はFCMへの移行が必要となります。移行手順は [FCMへの移行手順: Android](https://docs.repro.io/ja/releases/migration-to-fcm/android.md) をご覧ください。
- プッシュ通知をご利用いただくには、firebase-messaging バージョン17.1.0以降が必須となりました。
  - 現在 firebase-messaging バージョン17.1.0未満をご利用中の場合は、17.1.0以降に変更してください。
  - また、プッシュ通知の実装で `Repro.enablePushNotification()` の呼び出しが必須となりました。詳細は [プッシュ通知（Android）](https://docs.repro.io/ja/dev/sdk/push-notification/android.md) をご覧ください。
- バナータイプのアプリ内メッセージのフォントサイズを大きくし、メッセージの視認性を高めました。

##### NOTE
今回のリリースより、Eclipse ADTのサポートを廃止しました。Eclipse ADTをご利用中の場合はAndroid Studioに移行してください。移行に必要な作業は [Googleの公式ドキュメント](https://developer.android.com/studio/intro/migrate?hl=ja#migrate-eclipse) をご覧ください。



### 3.0.0 (2018/08/24)

変更

- データアップロードの処理を変更しました。
  - Android SDK 3.0.0未満は、2019年6月24日以降にセッションデータをアップロードできなくなります。
  - そのため、2019年6月24日までにAndroid SDK 3.0.0以上にアップデートしてください。



### 2.13.0 (2018/08/08)

変更

- 横向きで表示される際のアプリ内メッセージのレイアウトを変更しました。



### 2.12.6 (2018/07/19)

修正

- SDK内部で利用しているServiceの処理で待ちが発生しないよう改善しました。
- Android 5.xの端末で、アプリを停止してもSDK内部で利用しているServiceが停止しない不具合を修正しました。



### 2.12.2 (2018/06/29)

変更

- アプリ内メッセージの表示待ち時間が短くなるよう改善しました。
  - アプリ起動後にアプリ内メッセージの画像を予めダウンロードするようになりました。予めダウンロードが完了している場合は、トリガーイベント発生時に待ち時間無しでアプリ内メッセージが表示されます。
  - また、ダウンロード未完了の時にトリガーイベント発生した場合でも、3秒以内にダウンロード完了できない場合はアプリ内メッセージの表示をキャンセルするようになりました。
- 「購入」イベントの `value` と `currency` プロパティの指定が必須になりました。詳細は [購入](https://docs.repro.io/ja/dev/sdk/tracking.md#track-purchase) をご覧ください。
  - APIのシグネチャーを変更しました。 `trackPurchase` の第2引数で `value` を指定し、第3引数で `currency` を指定してください。
    ```diff
    - Repro.trackPurchase("content_id", null);
    + Repro.trackPurchase("content_id", 5000.0, "JPY", null);
    ```
  - WebViewから「購入」イベントをトラックする場合も `value` と `currency` が必須となります。
    - APIシグネチャーを変更した `v4/repro.js` を公開しました。`trackPurchase` の第2引数で `value` を指定し、第3引数で `currency` を指定してください。
      ```diff
      <head>
      -  <script src="//cdn.reproio.com/js/v3/repro.js" type="text/javascript" charset="utf-8"></script>
      +  <script src="//cdn.reproio.com/js/v4/repro.js" type="text/javascript" charset="utf-8"></script>
      </head>

      ...

      repro.trackPurchase("content_id", 5000.0, "JPY", {
        content_name: "Slim Jeans"
      });
      ```
    - なお、古い `v3/repro.js` をご利用の場合でも `value` と `currency` の指定は必須となります。 `v3/repro.js` をご利用し続ける場合は、 `trackPurchase` の第2引数に渡すオブジェクトで `value` と `currency` を指定してください。
      ```diff
      repro.trackPurchase("content_id", 5000.0, "JPY", {
        content_name: "Slim Jeans"
      });
      ```

修正

- Android 8.0以降の端末で、端末の画面がロックまたはスリープ状態の時にActivityがresumeすると例外発生する不具合を修正しました。



### 2.11.12 (2018/06/08)

修正

- `onCreate` で `setContentView` していないActivityを録画中に開くと、稀にクラッシュする不具合を修正しました。



### 2.11.10 (2018/05/11)

変更

- ユーザーIDがセットされていない状態で記録されたユーザープロフィールは、ユーザーIDをセットした後に引き継がれるように変更しました。



### 2.11.6 (2018/04/11)

修正

- 通信回線が低速の場合にアプリをフォアグラウンドからバックグラウンドに何度も切り替えると、セッションデータのアップロードに失敗してリトライし続ける不具合を修正しました。



### 2.11.0 (2018/03/20)

新機能

- アプリ内メッセージでコントロールグループ機能が利用できるようになりました。詳細は [こちら](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md) をご覧ください。

修正

- 録画のユーザー同意ダイアログ表示時に稀にクラッシュする不具合を修正しました。



### 2.10.7 (2018/03/02)

修正

- アプリをフォアグラウンドからバックグラウンドに切り替えると稀にクラッシュする不具合を修正しました



### 2.10.1 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。



### 2.10.0 (2018/01/18)

新機能

- アプリ内メッセージのボタン押下数の計測に対応しました。計測されたボタン押下数は管理画面から確認できます。詳細は [こちら](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md#inapp-measurement) をご覧ください。



### 2.9.10 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。



### 2.9.9 (2017/12/19)

修正

- アプリ内メッセージの画像を提供するサーバと3~6秒以内に通信を開始できない場合、アプリ内メッセージの表示をキャンセルするようになりました。



### 2.9.0 (2017/11/16)

新機能

- アプリを初めて起動したユーザーを対象にアプリ内メッセージを配信する機能を追加しました。



### 2.8.3 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。



### 2.8.2 (2017/11/06)

修正

- アプリのtargetSDKVersionが24以上かつAndroid N以降の機種で動作している場合、横向きにした端末でオーバーレイタイプのアプリ内メッセージを表示すると、画像が小さく表示される不具合を修正しました。



### 2.8.0 (2017/10/19)

新機能

- 指定したイベントが発生したタイミングで録画開始するトリガー録画機能を追加しました。



### 2.7.11 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。



### 2.7.10 (2017/10/17)

修正

- `android:configChanges="orientation|screenSize"` 属性が指定されたActivity上にアプリ内メッセージを表示している場合、端末の回転によってアプリ内メッセージのレイアウトが崩れる不具合を修正しました。



### 2.7.8 (2017/10/12)

変更

- スタンダード形式のプッシュ通知に対しても `Repro.markPushNotificationReceived` で「受信済み」と記録するようになりました。
  - カスタム（JSON）形式のプッシュ通知に対して [オプション：プッシュ通知受信時の動作をカスタマイズする](https://docs.repro.io/ja/dev/sdk/push-notification/android.md#customize-receiver) の手順で `Repro.markPushNotificationReceived` をご利用の場合は、これまで通りご利用いただけます。



### 2.7.2 (2017/09/15)

修正

- アプリ内メッセージの背景色が稀に適用されない不具合を修正しました。
- アプリ内メッセージの画像をロード中に端末を回転させるとアプリ内メッセージが表示されない不具合を修正しました。



### 2.7.1 (2017/08/23)

新機能

- 標準ユーザープロフィール(ユーザーを絞り込む上で典型的なプロフィール)をセットするためのAPIを追加しました。詳細は [ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md) を参照してください。
- FCMを用いてプッシュ通知をご利用いただけるようになりました。詳細は [プッシュ通知（Android）](https://docs.repro.io/ja/dev/sdk/push-notification/android.md) を参照してください。



### 2.6.12 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。



### 2.6.11 (2017/08/18)

新機能

- Android Oに対応しました
  - アプリのtargetSDKVersionが26以上の場合、Android O以降の機種でプッシュ通知を受信するために通知チャンネルの作成が必要となります。詳細は [こちら](https://docs.repro.io/ja/dev/sdk/push-notification/android.md#notification-channel-setting) を参照してください。

変更

- `${applicationId}.permission.C2D_MESSAGE` パーミッションを持たないアプリでもプッシュ許諾状態を正しく判定するようになりました。

修正

- 短い間隔で連続してアプリ内メッセージを表示しようとすると、アプリ内メッセージの背景色が透明になる不具合を修正しました。



### 2.6.8 (2017/08/04)

新機能

- WebView で標準イベントをトラックするためのAPIを追加しました。
  - HTMLから読み込むrepro.jsのURLを変更する必要があります。repro.jsの使い方の詳細は [こちら](https://docs.repro.io/ja/dev/sdk/webview.md) を参照してください。

  ```diff
   <head>
   ...
  -   <script src="//cdn.reproio.com/js/v2/repro.js" type="text/javascript" charset="utf-8"></script>
  +   <script src="//cdn.reproio.com/js/v3/repro.js" type="text/javascript" charset="utf-8"></script>
   ...
   </head>
  ```

変更

- Android 7.0 (API 24)以降でWebViewClientの `onUnhandledInputEvent` が削除されたことを受け、 `Repro.startWebViewTracking` に渡すWebViewClientについても `onUnhandledInputEvent` が呼び出されなくなります。代わりにWebViewClientの `onUnhandledKeyEvent` を使用してください。
  - 参考: [https://developer.android.com/sdk/api_diff/24/changes/android.webkit.WebViewClient.html](https://developer.android.com/sdk/api_diff/24/changes/android.webkit.WebViewClient.html)



### 2.6.0 (2017/07/03)

新機能

- 標準イベント(ユーザーの行動分析を行う上で典型的なイベント)をトラックするためのAPIを追加しました。詳細は [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md) を参照してください。

修正

- マルチウィンドウモードでアプリ使用中に、オーバーレイタイプのアプリ内メッセージを表示するとクラッシュする不具合を修正しました。



### 2.5.14 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。



### 2.5.13 (2017/06/02)

修正

- スクロール時にマスクがずれる不具合を修正しました
- 特定の端末でアプリ内メッセージ表示時にクラッシュする不具合を修正しました



### 2.5.0 (2017/05/23)

新機能

- アプリ内メッセージの色をカスタマイズできるようになりました。詳細は [アプリ内メッセージ](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md) を参照してください。



### 2.4.1 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。



### 2.4.0 (2017/05/19)

新機能

- 「初回起動」イベントの自動トラッキング機能を追加しました



### 2.3.17 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。



### 2.3.16

修正

- アプリ内メッセージ表示時に稀にクラッシュする不具合を修正しました



### 2.3.13

改善点

- アプリがバックグラウンドに遷移した時のパフォーマンスを改善しました



### 2.3.12

新機能

- デバイスIDとしてハッシュ化したANDROID_IDを利用できるようになりました。詳細は [デバイスID](https://docs.repro.io/ja/dev/sdk/device-id.md) をご覧ください。

改善点

- スタンダード形式で送信したプッシュ通知の本文が省略されないようになりました

修正

- アプリのアンインストール・再インストールを繰り返した場合にプッシュ通知が複数表示される不具合を修正しました
  - JSON形式のメッセージをご利用の場合は [こちら](https://docs.repro.io/ja/dev/sdk/push-notification/android.md#customize-receiver) を参考にアプリのGCMReceiverを実装してください。



### 2.3.9

改善点

- 通信処理の安定性を向上しました
- オーバーレイタイプのアプリ内メッセージの文字色を微調整しました



### 2.3.0

新機能

- ダイアログタイプのアプリ内メッセージで [画像のみのレイアウト](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md#dialog-image-only) を選択できるようになりました



### 2.2.1 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。



### 2.2.0

新機能

- Android 4.1~ で [リッチ通知メディア](https://docs.repro.io/ja/dashboard/campaign/push-notification.md#media) に対応しました。



### 2.1.23 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。



### 2.1.22

改善点

- [ユーザーID](https://docs.repro.io/ja/dev/sdk/user-id.md) とアプリバージョン名の文字列長をチェックするようにしました
  - [ユーザーID](https://docs.repro.io/ja/dev/sdk/user-id.md) は最大191文字です。最大文字数を超える場合は192文字以降を切り捨てます
  - アプリバージョン名は最大32文字です。最大文字数を超える場合は33文字以降を切り捨てます

修正

- デバイスの向きを検知する際に稀にクラッシュするバグを修正しました



### 2.1.11

修正

- Reproのサーバとの通信時にSSLハンドシェイクエラーとなるバグを修正しました

### 2.1.8

修正

- 大きいサイズのディスプレイをもつデバイスのアプリ内メッセージのサイズを修正しました。

### 2.1.7

新機能

- スクロール中の録画停止に対応しました。

改善点

- スクロール中のマスクサイズを拡大しました。

修正

- Webページのロード直後にマスクが外れるバグを修正しました。

### 2.1.2

修正

- アプリ内メッセージ(ダイアログタイプ)の画像サイズを修正しました。

### 2.1.0

新機能

- プッシュ通知開封時に、ディープリンク、URLを自動で開く機能を追加しました。



### 2.0.5 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。

### 2.0.4

修正

- アプリ内メッセージを閉じられなくなるバグを修正しました。



### 2.0.0

新機能

- ユーザープロフィールで文字列以外の型のデータを登録できるようになりました。下記のAPIをご利用ください。
  - `setIntUserProfile(String, int)`
  - `setDoubleUserProfile(String, double)`
  - `setDateUserProfile(String, Date)`
- `setUserProfile(String, String)` と `setUserProfile(HashMap<String, String>)` は削除されました。 `setStringUserProfile(String, String)` をお使いください。
  ```diff
  - Repro.setUserProfile("Job", "Developer");
  + Repro.setStringUserProfile("Job", "Developer");
  ```



### 1.2.10 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。

### 1.2.9

修正

- 空の動画ファイルをアップロードしないように修正しました。
- アプリ内メッセージを録画できるように修正しました。
- 非推奨のAPIを削除しました。



### 1.2.0

変更

- `setup(String)` は非推奨となりました。代わりに `setup(Application, String)` を使用してください。またこのメソッドは `Application#onCreate` から呼び出してください。詳細は [スタートガイドの「セットアップ」セクション](https://docs.repro.io/ja/dev/sdk/getstarted/android.md#android-setup) を参照してください。

修正

- WebView内でページ遷移したときにマスクが残ったままになる不具合を修正しました。
- いくつかのデバイスにおいてアプリ起動時にクラッシュするバグを修正しました。
- 稀に発生する録画開始できないバグを修正しました。



### 1.1.48 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。



### 1.1.47

改善

- アプリ内メッセージの画像をロード中にプログレスダイアログを表示するようにしました。

修正

- WebViewでページをロードした直後にイベントトラッキングに失敗する不具合を修正しました。WebViewトラッキングをご利用されている場合は、HTMLから読み込むJavaScriptファイルのURLを変更してください。
  ```diff
   <head>
   ...
  -   <script src="//cdn.reproio.com/js/v1/dummy.repro.js" type="text/javascript" charset="utf-8"></script>
  +   <script src="//cdn.reproio.com/js/v2/repro.js" type="text/javascript" charset="utf-8"></script>
   ...
   </head>
  ```
- アプリ内メッセージのレイアウトが崩れるバグを修正しました。
- デバイス回転時にクラッシュする可能性のあるバグを修正しました。



### 1.1.37

変更

- `enableCrashReporting()` API を廃止しました。
- `MessageActivity` は削除されました。下記の通り `AndroidManifest.xml` を修正してください。Android Studioをご利用の場合は自動で修正されるため、この手順は不要です。
  ```diff
       <service android:name="io.repro.android.ReproService" />
  -   <activity
  -       android:name="io.repro.android.message.MessageActivity"
  -       android:theme="@style/io_repro_android_MessageActivityTheme"/>
  ```

改善

- 録画の安定性を向上しました。
- アプリ内メッセージをロード中にプログレスバーを表示するよう変更しました。



### 1.1.29

変更

- Reproのプッシュ通知機能をご利用の場合は、以下のReceiverの設定を `AndroidManifest.xml` に追加してください。Android Studioをご利用の場合は自動で追加されるため、この手順は不要です。

```diff
    <receiver
         android:name="io.repro.android.GCMReceiver"
         android:exported="true"
         android:permission="com.google.android.c2dm.permission.SEND">
         <intent-filter>
             <action android:name="com.google.android.c2dm.intent.RECEIVE" />
             <category android:name="YOUR_PACKAGE_NAME" />
         </intent-filter>
     </receiver>

+    <receiver
+        android:name="io.repro.android.notification.IntentHandler"
+        android:exported="false">
+        <intent-filter>
+            <action android:name="io.repro.android.notification.IntentHandler.START_ACTIVITY" />
+        </intent-filter>
+    </receiver>
```

修正

- WebViewでイベントトラッキングをする際にクラッシュする可能性のあるバグを修正しました。

### 1.1.28

修正

- プッシュ通知開封計測のバグを修正しました。

### 1.1.26

新機能

- `getDeviceID` と `getUserID` API を追加しました。

改善

- Support.V4 への依存を削除しました。

変更

- ユーザープロフィールのキーと値の文字列長を制限しました。

修正

- プッシュ通知受信時に新しいメッセージで上書きしないように修正しました。
- 録画ポーズ中にタッチをトラックしないように修正しました。
- アプリをkillした際に、アプリ内メッセージが表示済みにならないバグを修正しました。
- CTA URLが設定されていない場合にCTAイベントをトラックできないバグを修正しました。

### 1.1.14

改善

- 録画の安定性を改善しました。
- アプリ内メッセージの表示の安定性を改善しました。
- コンフィギュレーションのリトライ機能を追加しました。
- 画像ダウンロード時にデフォルトのSSLContextを使うよう修正しました。

### 1.1.5

修正

- `Activity.onWindowFocusChanged` に登録したコールバックが正しく動作しないバグを修正しました。

### 1.1.4

修正

- 録画終了時にクラッシュするバグを修正しました。
- セッションデータが壊れる可能性のあるバグを修正しました。

### 1.1.2

新機能

- プッシュ通知の開封記録機能を追加しました。

改善

- スレッドセーフティを改善しました。
- アップロード時の安定性を改善しました。

修正

- セッションデータのアップロードの遅延を改善しました。
- アプリ内メッセージが2回表示されるバグを修正しました。
- クラッシュする可能性のあるバグを修正しました。



### 1.0.2 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。

### 1.0.1

新機能

- イベントトラッキング時にアプリ内メッセージを表示する機能を追加しました。

改善

- セッションと録画の安定性を改善しました。

修正

- 4G接続時にセッションをアップロードできないバグを修正しました。
- ポーズ中に動画を停止した際にクラッシュする可能性のあるバグを修正しました。
- Android 4.3以前のクラッシュレポートのフォーマットを修正しました。

変更

`SurveyActivity` は `MessageActivity` に名前が変わりました。下記の通り `AndroidManifest.xml` を修正してください。Android Studioをご利用の場合は自動で修正されるため、この手順は不要です。

```diff
     <service android:name="io.repro.android.ReproService" />
     <activity
-       android:name="io.repro.android.surveys.SurveyActivity"
-       android:theme="@style/io_repro_android_SurveyActivityTheme"/>
+        android:name="io.repro.android.message.MessageActivity"
+        android:theme="@style/io_repro_android_MessageActivityTheme"/>
```



### 0.15.1 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。

### 0.15.0

新機能

- WebViewマスキング機能を追加しました。

改善

- ユーザーIDをアプリ内に永続化するように変更しました。

修正

- セッションが重複してアップロードされる可能性のあるバグを修正しました。



### 0.14.6 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。

### 0.14.5

新機能

- アプリ内メッセージのパターンを追加しました。
  - ダイアログタイプのメッセージを使えるようになりました。
  - メッセージ中にボタンを2つ作成できるようになりました。

変更

- `track(String JSONObject)` API を非推奨にしました。 `track(String, Map<String, Object>)` をお使いください。

修正

- アプリをフォアグラウンドに戻したときにクラッシュするバグを修正しました。
- 録画の開始時にクラッシュするバグを修正しました。
- 古いセッションデータが削除されないバグを修正しました。



### 0.13.23 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。

### 0.13.22

変更

- イベント名の文字列の長さを255文字に制限しました。

修正

- インターネットに接続されていない場合はアップロードを試みないよう修正しました。
- デバイスを横向きで開始した際に、アプリの動画の向きが不正になるバグを修正しました。

### 0.13.18

修正

- `Activity.onTouchEvent` に登録したコールバックが呼ばれなくなるバグを修正しました。
- イベントの発生時刻が不正になるバグを修正しました。
- 録画の停止時にクラッシュする可能性のあるバグを修正しました。

### 0.13.15

改善

- プッシュ通知のアイコンの背景色をカスタマイズするオプションを追加しました。
- Ottoへの依存を削除しました。
- `maskWithRect` API を追加しました。

修正

- WebViewでトラックした文字列が文字化けする問題に対応しました。
- ダイアログ形式のアクティブティを録画中にクラッシュするバグを修正しました。
- マスキング中にクラッシュするバグを修正しました。
- 録画の確認ダイアログが重複する不具合を修正しました。

### 0.13.3

改善

- AWS SDKへの依存をなくしました。
- kotlin-stdlib への依存をなくしました。
- `ANDROID_ID` を収集しないようにするオプションを追加しました。

修正

- 動画のタッチの座標がおかしくなるバグを修正しました。
- 動画の順序がおかしくなるバグを修正しました。

### 0.12.0

新機能

- Unityをサポートしました(画面録画を除く)。

### 0.11.7

修正

- キーイベントの取得が動作しなくなるバグを修正しました。
- マスク対象の親となるViewがいなくなった際にマスクが残るバグを修正しました。

### 0.11.4

改善

- アプリ内メッセージで大きいサイズの画像を使えるように修正しました。

修正

- Eclipseでアプリを作成時に発生する可能性のある不具合を修正しました。
- マスキングの不具合を修正しました。

### 0.11.0

新機能

- ユーザープロフィール: プッシュ通知やアプリ内メッセージの配信対象をユーザーの属性情報でセグメントできるようになります。 [詳細はこちらをご覧ください](http://docs.repro.io/en/api/user-profile.html)

改善

- 古い Play Service SDK をサポートしました。
  - Play Service SDK 3.1.36~ でプッシュ通知を受信する際は [こちらをご覧ください](http://docs.repro.io/en/manual/push-notification-android.html)
- 画面録画中のメモリ使用量と動作の安定性を改善しました。

### 0.10.1

新機能

- Eclipse ADTをサポートしました。

改善

- VolleyPlusへの依存をなくしました。

### 0.9.3

新機能

- プッシュ通知
- アプリ内メッセージ
- WebViewのイベントトラッキング

改善

- Android 4系に対応しました。
  - Android 2.3~: インストールは可能ですが、機能は動作しません。
  - Android 4.0~: 録画以外の機能を利用できます。
  - Android 4.3~: すべての機能を利用できます。
- Android エミュレータをサポートしました。
  - **注意:** 画面録画はサポートしていません。
- 画面録画中のメモリ使用量を改善しました。

### 0.8.20

- 公式リリース

---

## Android SDK 更新手順

最新のrepro-android-sdkを参照するよう **app/build.gradle** を変更してください

`settings.gradle` に以下を追記してください。（古いバージョンのGradleでプロジェクトを作成した場合には `app/build.gradle` 内に追記してください）

```groovy
 repositories {
     ...
     maven { url 'https://cdn.reproio.com/android' }
     ...
 }
```

アプリケーションの `app/build.gradle` に以下を記述してください。

```groovy
 dependencies {
     ...
     implementation 'io.repro:repro-android-sdk:5.24.0'
     ...
 }
```

##### NOTE
Gradle 3.4 未満のバージョンの場合は 'implementation' が利用できません。
'compile'を利用してください。

---

## FCMへの移行手順: Android

Googleからアナウンスされている通り、GCMは2019/4/11までに廃止が予定されております。すでにReproのプッシュ通知をGCMで実装している場合は、それまでに以下の手順を参照し、FCMでの実装に移行してください。

### 移行手順

#### Google Cloud PlatformのプロジェクトをFirebase Consoleへ移行する

Firebase ConsoleからGCMで利用していたプロジェクトを選択して作成してください：


* Google Cloud Platformのプロジェクト番号と、Firebase Consoleの送信者IDが同一であるか確認してください。Google Cloud Platformのプロジェクト番号は **Google Cloud Platform > IAMと管理 > 設定** のプロジェクト番号から確認できます：
  
* Firebase Consoleの送信者IDは **設定 > クラウドメッセージング** の送信者IDから確認できます：
  

#### FCMを設定する

1. [アプリの登録](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md#firebase-register-app) の手順を参照し、 `google-services.json` をダウンロードしてください。
2. [Firebaseの秘密鍵を生成](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md#firebase-generate-private-key) と [Firebaseの秘密鍵をReproに登録](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md#firebase-register-private-key) の手順を参照し、Firebaseの秘密鍵をReproに登録してください。

#### Repro Android SDKのアップデート

アプリケーションの `app/build.gradle` を開き、 `repro-android-sdk` のバージョンを `3.1.1` 以上に変更してください：

```diff
 dependencies {
     ...
-    implementation 'io.repro:repro-android-sdk:3.0.0'
+    implementation 'io.repro:repro-android-sdk:3.1.1'
     ...
 }
```

#### Firebase SDKを導入する

1. `google-services.json` をアプリモジュールのディレクトリにコピーしてください。
2. プロジェクトのbuild.gradleを以下のように修正してください：
   ```diff
    buildscript {
        ...
        dependencies {
            ...
   +        classpath 'com.google.gms:google-services:4.2.0'
        }
    }

    allprojects {
        ...
        repositories {
            ...
   +        google()
        }
    }
   ```
3. アプリのbuild.gradleに以下のように修正してください：
   ```diff
    dependencies {
   -    implementation 'com.google.android.gms:play-services-gcm:15.0.1'
   +    implementation 'com.google.firebase:firebase-core:16.0.4'
   +    implementation 'com.google.firebase:firebase-messaging:17.3.4'
        ...
    }

   +apply plugin: 'com.google.gms.google-services'
   ```

#### AndroidManifest.xmlファイルを編集する

`io.repro.android.GCMReceiver` を `io.repro.ReproReceiver` に修正してください：

```diff
 <receiver
-    android:name="io.repro.android.GCMReceiver"
+    android:name="io.repro.android.ReproReceiver"
     android:exported="true"
     android:permission="com.google.android.c2dm.permission.SEND">
     <intent-filter>
         <action android:name="com.google.android.c2dm.intent.RECEIVE" />
         <category android:name="YOUR_PACKAGE_NAME" />
     </intent-filter>
 </receiver>
```

#### Registration IDの取得方法を変更する

1. `Repro.enablePushNotification` の呼び出しの引数を削除してください。
   ```diff
    import io.repro.android.Repro;

    public class MyApplication extends Application {

        @Override
        public void onCreate() {
            super.onCreate();

            ...

            Repro.setup(this, "YOUR_APP_TOKEN");
   -        Repro.enablePushNotification("SENDER_ID");
   +        Repro.enablePushNotification();

            ...
        }
    }
   ```
2. `FirebaseMessagingService` を継承したクラスの `onNewToken` にて `Repro.setPushRegistrationID` を呼び出してください。
   ```java
       import io.repro.android.Repro;

       public class MyFirebaseMessagingService extends FirebaseMessagingService {
           ...
           @Override
           public void onNewToken(String token) {
               Repro.setPushRegistrationID(token);
           }
           ...
       }
   ```
3. 以下をAndroidManifest.xmlの `<application>` タグの中に追加してください。
   ```xml
   <service
       android:name=".MyFirebaseMessagingService">
       <intent-filter>
           <action android:name="com.google.firebase.MESSAGING_EVENT" />
       </intent-filter>
   </service>
   ```

#### カスタムReceiver

##### カスタムReceiverを引続き利用する

カスタムReceiverを実装している場合、FCMへ移行後も引続き利用可能です。この場合、カスタムReceiverが継承するクラスを `ReproReceiver` に変更してください。

```diff
-public class Receiver extends io.repro.android.GCMReceiver {
+public class Receiver extends io.repro.android.ReproReceiver {
     @Override
     public void onReceive(Context context, Intent intent) {
         ...
```

##### カスタムReceiverをFirebaseMessagingServiceに移行する

カスタムReceiverからFirebaseMessagingServiceへ移行する場合は、下記の手順を参考してください。

1. カスタムReceiverを削除し、 `AndroidManifest.xml` から下記のタグを削除してください：
   ```xml
   <receiver
       android:name="your.package.name.GCMReceiver"
       android:exported="true"
       android:permission="com.google.android.c2dm.permission.SEND">
       <intent-filter>
           <action android:name="com.google.android.c2dm.intent.RECEIVE" />
           <category android:name="your.package.name" />
       </intent-filter>
   </receiver>
   ```
2. 以下のXML中の "YOUR_PACKAGE_NAME" をアプリケーションのパッケージ名に置き換え、AndroidManifest.xmlの `<application>` タグの中に追加してください。
   ```xml
   <receiver
       android:name="io.repro.android.ReproReceiver"
       android:exported="true"
       android:permission="com.google.android.c2dm.permission.SEND">
       <intent-filter>
           <action android:name="com.google.android.c2dm.intent.RECEIVE" />
           <category android:name="YOUR_PACKAGE_NAME" />
       </intent-filter>
   </receiver>
   ```

   #### NOTE
   AndroidManifest内のreceiverの登録は、FCM移行後も必要になります。
3. [プッシュ通知受信時の動作をカスタマイズする](https://docs.repro.io/ja/dev/sdk/push-notification/android.md#customize-receiver) を参照し、FirebaseMessagingServiceのonMessageReceivedメソッドを実装してください

---

java, kotlin

## 導入: Android

### SDKをインストールする

プロジェクトのReproへの依存を追加します。

`settings.gradle` に以下を追記してください。（古いバージョンのGradleでプロジェクトを作成した場合には `app/build.gradle` 内に追記してください）

```groovy
 repositories {
     ...
     maven { url 'https://cdn.reproio.com/android' }
     ...
 }
```

アプリケーションの `app/build.gradle` に以下を記述してください。

```groovy
 dependencies {
     ...
     implementation 'io.repro:repro-android-sdk:5.24.0'
     ...
 }
```

##### NOTE
Gradle 3.4 未満のバージョンの場合は 'implementation' が利用できません。
'compile'を利用してください。

Repro SDKを使用するにはアプリケーションに以下のパーミッションが必要です。これらのパーミッションはAndroid Studioの「Manifest Merging」機能によって自動で追加されるため、`AndroidManifest.xml` に手動で追加する必要はありません。

* `android.permission.INTERNET`
* `android.permission.ACCESS_NETWORK_STATE`

##### NOTE
Manifest Mergingの詳細については  [こちらの記事](https://developer.android.com/studio/build/manifest-merge.html?hl=ja)  をご覧ください。



#### MultiDex

Androidアプリケーション (APK) は、実行コードとしてDalvik Executable (DEX)形式のファイルを内部に持っています。このDEXファイルの仕様上、1つのDEXファイルから参照できるメソッド数は65536個までと制限されています。Repro SDKを導入することにより、アプリケーションから参照されるメソッド数が65536個を超える場合、アプリケーションのMultiDex化が必要です。

エラーメッセージ例:

```
com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command '/Library/Java/JavaVirtualMachines/jdk1.8.0_51.jdk/Contents/Home/bin/java'' finished with non-zero exit value 2
```

このエラーを回避するために、アプリケーションのbuild.gradleファイルに以下を追加してください。

```groovy
android {
    defaultConfig {
        multiDexEnabled true
    }
}
```

##### NOTE
DEXファイルの制限事項とMultiDex化の詳細については、 [こちらの記事](https://developer.android.com/studio/build/multidex.html?hl=ja) をご覧ください。

インストールが完了したら [セットアップ](#android-setup) に進んでください。

#### ProGuard

Repro SDKを導入したアプリケーションにProGuardを適用する場合は、以下のルールを指定してください。

```
-dontwarn io.repro.android.**
-keep class io.repro.android.** { *; }
```

##### NOTE
この設定は、Repro Android SDK 5.5.1 以上のバージョンでは実施する必要はありません。



#### エッジ ツー エッジ

エッジ ツー エッジはRepro Android SDK 5.22.0で対応されました。

そのため、エッジ ツー エッジに対応したアプリでRepro Android SDK 5.21.0 以下をご利用いただく場合、アプリ内メッセージを表示したときにステータスバーやナビゲーションバーのデザインがアプリに設定されたものから一時的に変更される可能性があることにご留意ください。



### セットアップ

独自のApplicationクラスを実装していない場合は、実装して `AndroidManifest.xml` に以下のように指定してください。

```xml
<application android:name="YOUR_APPLICATION_CLASS_NAME">
```

Applicationの `onCreate` メソッドで新しい [セッション](https://docs.repro.io/ja/dev/sdk/session.md) を開始してください。

`YOUR_APP_TOKEN` には管理画面の **設定 > プロジェクト設定 > 認証情報** に記載されている **SDK トークン** を設定してください。

```java
import io.repro.android.Repro;

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        ...

        // Setup Repro
        Repro.setup(this, "YOUR_APP_TOKEN");

        ...
    }
}
```

```kotlin
import io.repro.android.Repro

class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        ...

        // Setup Repro
        Repro.setup(this, "YOUR_APP_TOKEN")

        ...
    }
}
```

SDKが収集した情報は定期的にサーバーにアップロードされます。

### イベントをトラックする

意味のある分析や、マーケティング施策を実施するためには、適切なユーザーグループを絞り込むことが重要です。イベントをトラックしてユーザーの行動を記録することにより、管理画面上で目的に応じた適切なユーザーグループを選択することができるようになります。

イベントを用いたユーザーグループ指定の例:

- [キャンペーンの作成画面で、イベントやユーザープロフィールを組み合わせて、配信対象となるユーザーグループを指定する](https://docs.repro.io/ja/dashboard/campaign/target.md)

どういうイベントをとるべきかわからない場合は、まず各画面の表示時にイベントをとってみることをおすすめします。

例:

```objc
@implementation MainViewController

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [Repro track:@"MainViewController" properties:nil];

    ...
}
```

```swift
class MainViewController: UIViewController {

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        Repro.track(event: "MainViewController", properties: [:])

        ...
    }
```

```java
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onResume() {
        super.onResume();
        Repro.track("MainActivity");

        ...
    }
}
```

```kotlin
class MainActivity : AppCompatActivity() {

    override fun onResume() {
        super.onResume()
        Repro.track("MainActivity")

        ...
    }
}
```

```cpp
#include "ReproCpp.h"

...

ReproCpp::track("Initialized");
```

```csharp
Repro.Track ("Initialized");
```

```js-cordova
// Will be written later
```

```js-react-native
class MainScreen extends React.Component {

    componentDidMount() {
        Repro.track("MainScreen", {});
    }

    ...
 }
```

```js-expo
import Repro from 'react-native-repro';

...

Repro.track("MainScreen", {});
```

```dart
import 'package:repro_flutter/repro.dart';

...

await Repro.track("Initialized");
```

### ユーザーIDをセットする

Repro では分析結果はユーザー単位で集計しています。ユーザーIDをセットすることにより、下記のメリットがあります:

- 複数のデバイスを使っているユーザーを同一視できる
- キャンペーンの配信対象の抽出がより精緻になる

詳しくは [こちら](https://docs.repro.io/ja/dev/sdk/user-id.md) をご覧ください。

### プッシュ通知を配信する

Reproでは、管理画面もしくはAPIからプッシュ通知配信をすることができます。プッシュ通知配信をするための実装は [こちら](https://docs.repro.io/ja/dev/sdk/push-notification/index.md) をご覧ください。

### Next...

その他の機能についての詳細は、以下をご覧ください。

- [セッション・ライフサイクル](https://docs.repro.io/ja/dev/sdk/session.md)
- [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md)
- [ユーザーID](https://docs.repro.io/ja/dev/sdk/user-id.md)
- [デバイスID](https://docs.repro.io/ja/dev/sdk/device-id.md)
- [ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md)
- [WebView](https://docs.repro.io/ja/dev/sdk/webview.md)
- [オプトアウト機能](https://docs.repro.io/ja/dev/sdk/optout/index.md)
- [アプリ内メッセージ](https://docs.repro.io/ja/dev/sdk/in-app-message.md)
- [プッシュ通知](https://docs.repro.io/ja/dev/sdk/push-notification/index.md)
- [Adjustで取得したアトリビューションデータをReproにセットする](https://docs.repro.io/ja/dev/sdk/integrate-adjust.md)
- [AppsFlyerで取得したアトリビューションデータをReproにセットする](https://docs.repro.io/ja/dev/sdk/integrate-appsflyer.md)

---

## Unity Package リリースノート

* [Unity Package 更新手順](https://docs.repro.io/ja/releases/sdk/unity/upgrade.md)
  * [5.2.0以降](https://docs.repro.io/ja/releases/sdk/unity/upgrade.md#id1)
  * [2.0.0以降](https://docs.repro.io/ja/releases/sdk/unity/upgrade.md#id2)
  * [1.3.0 からのアップグレード](https://docs.repro.io/ja/releases/sdk/unity/upgrade.md#id3)
  * [0.0.8 ~ 1.2.1からのアップグレード](https://docs.repro.io/ja/releases/sdk/unity/upgrade.md#id4)
  * [0.0.1 ~ 0.0.6からのアップグレード](https://docs.repro.io/ja/releases/sdk/unity/upgrade.md#id5)



### 6.25.1 (2026/07/01)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.24.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-24-1)
  - [Android SDK 5.24.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-24-0)



### 6.25.0 (2026/04/01)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [Android SDK 5.22.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-22-0)



### 6.24.0 (2026/03/05)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.23.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-23-0)
  - [Android SDK 5.21.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-21-0)



### 6.23.1 (2026/01/27)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.22.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-22-1)
  - [Android SDK 5.20.7](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-20-7)



### 6.23.0 (2025/12/15)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.22.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-22-0)



### 6.22.4 (2025/11/18)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [Android SDK 5.20.4](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-20-4)



### 6.22.3 (2025/11/14)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.21.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-21-1)
  - [Android SDK 5.20.3](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-20-3)



### 6.22.2 (2025/10/23)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [Android SDK 5.20.2](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-20-2)



### 6.22.1 (2025/09/29)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [Android SDK 5.20.1](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-20-1)



### 6.22.0 (2025/07/28)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.21.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-21-0)
  - [Android SDK 5.20.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-20-0)



### 6.21.0 (2025/04/25)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.20.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-20-0)
  - [Android SDK 5.19.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-19-0)



### 6.20.0 (2024/12/26)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.19.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-19-0)
  - [Android SDK 5.18.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-18-0)



### 6.19.1 (2024/10/30)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [Android SDK 5.17.1](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-17-1)



### 6.19.0 (2024/10/03)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.18.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-18-0)
  - [Android SDK 5.17.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-17-0)



### 6.18.0 (2024/07/11)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.17.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-17-0)
  - [Android SDK 5.16.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-16-0)



### 6.17.0 (2024/05/17)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.16.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-16-0)
  - [Android SDK 5.15.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-15-0)



### 6.16.0 (2024/04/30)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.15.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-15-0)
  - [Android SDK 5.14.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-14-0)



### 6.15.0 (2024/01/19)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.14.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-14-0)
  - [Android SDK 5.13.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-13-0)



### 6.14.1 (2023/12/22)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.13.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-13-1)



### 6.14.0 (2023/11/17)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.13.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-13-0)
    - 本バージョンのUnity PackageにおいてはiOS SDKのコード署名には対応していません。
  - [Android SDK 5.12.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-12-0)



### 6.13.0 (2023/10/16)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.12.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-12-0)
  - [Android SDK 5.11.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-11-0)



### 6.12.0 (2023/09/12)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.11.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-11-1)
  - [Android SDK 5.10.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-10-0)



### 6.11.0 (2023/06/13)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.11.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-11-0)
  - [Android SDK 5.9.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-9-0)



### 6.10.0 (2023/03/08)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.9.5](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-9-5)
  - [Android SDK 5.8.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-8-0)



### 6.9.5  (2023/02/14)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.9.4](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-9-4)



### 6.9.4  (2022/12/28)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.9.3](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-9-3)
  - [Android SDK 5.7.2](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-7-2)



### 6.9.3  (2022/10/27)

修正

- iOS Build Support機能が導入されていない環境でアプリのビルドに失敗する問題を修正しました。



### 6.9.2  (2022/10/17)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.9.2](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-9-2)



### 6.9.1  (2022/10/05)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.9.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-9-1)
  - [Android SDK 5.7.1](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-7-1)



### 6.9.0  (2022/08/31)

新機能

- ユニバーサルリンク･アプリリンクに対応するためのコールバック処理の記述が可能になりました。
  - 詳細は [こちら](https://docs.repro.io/ja/dev/sdk/push-notification/unity.md#universal-link-guide-unity) をご覧ください。

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.9.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-9-0)
  - [Android SDK 5.7.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-7-0)



### 6.8.0  (2022/04/12)

変更

- サポート品質の向上のため、クロスプラットフォーム環境におけるSDKの情報を取得する機能を追加しました。
- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.8.3](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-8-3)
  - [Android SDK 5.6.3](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-6-3)



### 6.7.0  (2021/12/07)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.8.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-8-0)
  - [Android SDK 5.6.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-6-0)



### 6.6.0  (2021/08/04)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.6.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-6-0)
  - [Android SDK 5.5.1](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-5-1)



### 6.5.0  (2021/06/03)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.5.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-5-1)
  - [Android SDK 5.4.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-4-0)



### 6.4.0  (2021/03/09)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.4.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-4-0)
  - [Android SDK 5.3.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-3-0)



### 6.3.0  (2021/02/02)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.3.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-3-0)
  - [Android SDK 5.2.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-2-0)



### 6.2.1  (2020/12/23)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.2.12](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-2-12)
  - [Android SDK 5.1.9](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-1-9)



### 6.2.0 (2020/11/02)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.2.2](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-2-2)
  - [Android SDK 5.1.3](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-1-3)



### 6.1.0 (2020/10/15)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.2.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-2-0)

修正

- `CFNetwork.framework` に関するリンクエラーの不具合を解決しました。



### 6.0.0 (2020/08/21)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.1.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-1-0)
  - [Android SDK 5.1.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-1-0)
- ニュースフィード機能およびAIレコメンド・アプリ内メッセージ連携機能（クローズドβ）に関するAPIを追加しました。
  - ニュースフィード機能についての詳細は [こちら](https://docs.repro.io/ja/dev/sdk/newsfeed.md) をご覧ください。



### 5.3.0 (2020/07/08)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 4.7.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-4-7-1)
  - [Android SDK 4.4.1](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-4-4-1)
- UXオプティマイザー機能（クローズドβ）に関するAPIを追加しました。
  - 詳細は [こちら](https://docs.repro.io/ja/dev/sdk/remote-config/unity.md) をご覧ください。



### 5.2.0 (2020/03/26)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 4.7.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-4-7-0)
  - [Android SDK 4.4.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-4-4-0)
- Unity2019.3から導入された "Unity as a Library" に対応したビルド処理にしました。
- iOS向けにアイコンバッジを消去するメソッドを追加しました。
  : - `Repro.ClearBadge()`

修正

- AndroidでのLogLevelに "None"（ログ出力なし）をセットできるようにしました。
  : - `Repro.SetLogLevel(string loglevel)` にObsolete属性をつけました修正。
- iOS, Android以外のビルドプラットフォームでビルドした場合に、ビルドエラーを起こす問題を修正しました。
- Windows環境でAndroidプラットフォームでaabのビルドした場合に、ビルドエラーを起こす問題を修正しました。
- Obsolete属性をつけていたメソッドを削除しました
  - `Repro.TrackWithProperties (string eventName, Dictionary<string, string> properties)`

##### WARNING
- 本リリースより、Unity 5.2.0以上でビルドすることが必須になります。
- 以前のバージョンからUnity Package 5.2.0以上のバージョンにアップグレードする場合、 [こちらの手順](https://docs.repro.io/ja/releases/sdk/unity/upgrade.md#unity-package-5-2-0-upgrade) を参照してください。



### 5.1.1 (2019/12/24)

変更

- Androidアプリのビルド時にエラーが出てビルド失敗する不具合を修正しました。詳しくは [こちら](#unity-dependency-error-5-1-0) をご覧ください。
- Repro iOS SDKで使用している WebKit.framework の依存を解決するように修正しました。



### 5.1.0 (2019/11/27)

変更

- Androidアプリをビルドした際に自動でパーミッションが付く問題を修正しました。この修正により、古いバージョンのUnityを利用してAndroidアプリをビルドした際にエラー出ることがあります。このエラーの対応方法については [こちら](https://docs.repro.io/ja/dev/sdk/getstarted/old-version-unity.md) をご覧ください。
- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 4.4.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-4-4-0)
  - [Android SDK 4.2.1](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-4-2-1)



##### WARNING
このバージョンでは、Unitypackageをインポートした際に `repro-4.2.1.jar` ファイルが追加され、以下のエラーによってAndroidアプリのビルドに失敗することがあります。その場合は、Repro Unity SDK 5.1.1にアップデートし、かつ `Assets > Plugins > Android > libs > repro-4.2.1.jar` ファイルを削除することで解決されます。

```
Program type already present: io.repro.android.ReproService$1
```

##### WARNING
このバージョンでは、Repro iOS SDKで使用している `WebKit.framework` 依存の追加を必要とする場合があります。その場合は、Repro Unity SDK 5.1.1にアップデートすることで解決されます。



### 5.0.0 (2019/09/05)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 4.2.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-4-2-0)
  - [Android SDK 4.1.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-4-1-0)



### 4.3.1  (2019/04/11)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 3.3.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-3-3-1)



### 4.3.0  (2019/04/05)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 3.3.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-3-3-0)



### 4.2.2 (2019/03/14)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 3.2.2](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-3-2-2)
- オプトアウト機能用のAPIを追加しました。
  - 詳細は [こちら](https://docs.repro.io/ja/dev/sdk/optout/index.md) をご覧ください。



### 4.2.0 (2019/02/15)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 3.2.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-3-2-0)
  - [Android SDK 3.3.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-3-3-0)
- 動画機能に関する主要なコードを削除し、動画機能が動作しないようにしました。以下のAPIを呼び出しても問題ありませんが何も実行されません。
  - `StartRecording`
  - `StopRecording`
  - `PauseRecording`
  - `ResumeRecording`
  - `ForceCaptureOnMainThread`
  - `MaskWithRect`
  - `UnmaskWithRect`

  #### WARNING
  録画関連APIは削除されました。2019年5月22日現在、これを利用することはできません。



### 4.1.1 (2018/11/22)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 3.0.6](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-3-0-6)



### 4.1.0 (2018/11/14)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 3.0.4](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-3-0-4)
  - [Android SDK 3.1.1](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-3-1-1)
- GCMのサポートを廃止しました。
  - GCMをご利用中の場合はFCMへの移行が必要となります。移行手順は [FCMへの移行手順: Unity](https://docs.repro.io/ja/releases/migration-to-fcm/unity.md) をご覧ください。
- プッシュ通知をご利用いただくには、firebase-messaging バージョン17.1.0以降が必須となりました。
  - 現在 firebase-messaging バージョン17.1.0未満をご利用中の場合は、17.1.0以降に変更してください。
  - また、プッシュ通知の実装で `Repro.enablePushNotification()` の呼び出しが必須となりました。詳細は [プッシュ通知 (Unity)](https://docs.repro.io/ja/dev/sdk/push-notification/unity.md) をご覧ください。
- 標準イベントをトラックするためのAPIを追加しました。詳細は [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md) を参照してください。

##### NOTE
今回のリリースより、Unity4のサポートを廃止しました。Unity4をご利用中の場合は、Unity5以上に移行してください。移行に必要な作業は [Unityの公式ドキュメント](https://docs.unity3d.com/Manual/UpgradeGuide5.html) をご覧ください。

##### NOTE
iPhone 7以降かつiOS12以上の端末では録画機能が無効となります。

**録画機能を無効とする背景**

iOS12の不具合の影響で、iPhone 7以降かつiOS12以上の端末で録画機能を利用すると、端末の負荷が増大するという現象が発生します。この現象を回避するため、録画機能を無効としています。また [iOS SDK 3.0.3](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-3-0-3) にて暫定的に録画可能としましたが、この暫定措置ではUnityアプリの画面が録画できません。

**今後の見通し**

AppleにはiOS12の不具合を報告済みです。Apple側の修正が完了次第、iPhone 7以降かつiOS12以上の端末でも録画可能となるSDKのリリースを検討します。



### 4.0.0 (2018/08/27)

SDKを更新しました。

- [iOS SDK 3.0.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-3-0-0)
- [Android SDK 3.0.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-3-0-0)

データアップロードの処理を変更しました。

- Unity Package 4.0.0未満は、2019年6月24日以降にセッションデータをアップロードできなくなります。
- そのため、2019年6月24日までにUnity Package 4.0.0以上にアップデートしてください。



### 3.12.0 (2018/08/09)

変更

SDKを更新しました。

- [iOS SDK 2.13.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-2-13-0)
- [Android SDK 2.13.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-2-13-0)



### 3.11.0 (2018/07/20)

変更

SDKを更新しました。

- [iOS SDK 2.12.2](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-2-12-2)
- [Android SDK 2.12.6](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-2-12-6)

iOSプラットフォームのdeployment targetを6.0から8.0に変更しました。詳細はiOS SDK 2.12.2の [リリースノート](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-2-12-2) をご覧ください。



### 3.9.0 (2018/03/28)

変更

SDKを更新しました。

- [iOS SDK 2.10.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-2-10-0)
- [Android SDK 2.11.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-2-11-0)

AndroidプラットフォームでFCMのRegistration IDをご利用いただけるようになりました。詳細は [こちら](https://docs.repro.io/ja/dev/sdk/push-notification/unity.md) をご覧ください。



### 3.5.1 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。

Unity Packageに同梱されているiOS SDKおよびAndroid SDKのバージョン

- [iOS SDK 2.6.10](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-2-6-10)
- [Android SDK 2.7.11](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-2-7-11)



### 3.5.0 (2017/10/18)

SDKを更新しました。

- [iOS SDK 2.6.9](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-2-6-9)
- [Android SDK 2.7.10](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-2-7-10)



### 3.1.3 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。

Unity Packageに同梱されているiOS SDKおよびAndroid SDKのバージョン

- [iOS SDK 2.1.13](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-2-1-13)
- [Android SDK 2.1.23](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-2-1-23)

### 3.1.2

SDKを更新しました。

- iOS SDK: 2.1.12
- Android SDK: 2.1.11

### 3.1.1

SDKを更新しました。

- iOS SDK: 2.1.3
- Android SDK: 2.1.2

### 3.1.0

SDKを更新しました。

- iOS SDK: 2.1.0
- Android SDK: 2.1.0



### 3.0.3 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。

Unity Packageに同梱されているiOS SDKおよびAndroid SDKのバージョン

- [iOS SDK 2.0.10](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-2-0-10)
- [Android SDK 2.0.5](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-2-0-5)

### 3.0.2

SDKを更新しました。

- iOS SDK: 2.0.9

### 3.0.1

SDKを更新しました。

- iOS SDK: 2.0.6

### 3.0.0

SDKを更新しました。

- iOS SDK: 2.0.0
- Android SDK: 2.0.0



### 2.1.3 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。

Unity Packageに同梱されているiOS SDKおよびAndroid SDKのバージョン

- [iOS SDK 1.7.35](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-1-7-35)
- [Android SDK 1.2.10](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-1-2-10)

### 2.1.2

SDKを更新しました。

- iOS SDK: 1.7.34
- Android SDK: 1.2.9

### 2.1.1

- Unity 4.7 をサポートしました。

### 2.1.0

SDKを更新しました。

- Android SDK: 1.2.0

変更

- 2.1.0より前のバージョンでは、SDKの初期化を `io.repro.android.UnityPlayerActivity#onCreate` で行っていましたが、この初期化処理は2.1.0以降のバージョンで非推奨となりました。2.1.0以降では、 `io.repro.android.UnityApplication#onCreate` にてSDKの初期化を行います。
- `Assets/Plugins/Android/AndroidManifest.xml` を以下のように更新してください。
  - メインActivityの **android:name** 属性を **com.unity3d.player.UnityPlayerActivity** に置き換えてください。
    ```diff
    -  <activity android:name="io.repro.android.UnityPlayerActivity">
    +   <activity android:name="com.unity3d.player.UnityPlayerActivity">
              <intent-filter>
                      <action android:name="android.intent.action.MAIN" />
                      <category android:name="android.intent.category.LAUNCHER" />
                      <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
              </intent-filter>
              <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
              <meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="false" />
        </activity>
    ```
- **application** エレメントの **android:name** 属性に **io.repro.android.UnityApplication** を指定してください。すでに独自のApplicationクラスを指定している場合は、SDKの初期化をするため [こちら](https://docs.repro.io/ja/dev/sdk/getstarted/unity.md#unity-custom-application-class) をご覧ください。
  ```diff
  +   <application android:name="io.repro.android.UnityApplication" ...
  ```



### 2.0.3 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。

Unity Packageに同梱されているiOS SDKおよびAndroid SDKのバージョン

- [iOS SDK 1.7.35](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-1-7-35)
- [Android SDK 1.1.48](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-1-1-48)

### 2.0.2

SDKを更新しました。

- iOS SDK: 1.7.30
- Android SDK: 1.1.47

### 2.0.0

SDKを更新しました。

- iOS SDK: 1.7.19
- Android SDK: 1.1.37

### 1.3.0

Android をサポートしました。

- iOS SDK: 1.4.14
- Android SDK: 0.12.0

### 1.2.1

SDKを更新しました。

- iOS SDK: 1.3.23

### 1.2.0

SDKを更新しました。

- iOS SDK: 1.3.19

### 1.1.1

SDKを更新しました。

- iOS SDK: 1.2.10.1

### 1.1.0

SDKを更新しました。

- iOS SDK: 1.2.10

### 1.0.0

SDKを更新しました。

- iOS SDK: 1.0.5

---

## Unity Package 更新手順

### 5.2.0以降



#### Unity5.2以上

1. 下記を削除してください。
   : - `Assets/Editor/Repro`
     - `Assets/Plugins/Repro`
     - `Assets/Plugins/iOS/Repro`
     - `Assets/Plugins/Android/Repro`
     - `Assets/Plugins/Android/libs/repro-android-sdk-x.x.x.aar`
2. 新しいSDKをインストールしてください。
   : - **Assets > Import Package > Custom Package...** を選択します
     - `Repro.unitypackage` をImportします

### 2.0.0以降

#### Unity5

1. 下記を削除してください。
   : - `Assets/Editor/Repro`
     - `Assets/Plugins/Repro`
     - `Assets/Plugins/iOS/Repro`
     - `Assets/Plugins/Android/Repro`
     - `Assets/Plugins/Android/libs/repro-android-sdk-x.x.x.aar`
2. 新しいSDKをインストールしてください。
   : - **Assets > Import Package > Custom Package...** を選択します
     - `Repro-unity5.unitypackage` をImportします

#### Unity4

1. 下記を削除してください。
   : - `Assets/Editor/Repro`
     - `Assets/Plugins/Repro`
     - `Assets/Plugins/iOS/Repro`
     - `Assets/Plugins/Android/Repro`
2. 新しいSDKをインストールしてください。
   : - **Assets > Import Package > Custom Package...** を選択します
     - `Repro-unity4.unitypackage` をImportします

### 1.3.0 からのアップグレード

#### Unity 5

1. 下記を削除してください。
   : - `Assets/Editor/Repro`
     - `Assets/Plugins/Repro`
     - `Assets/Plugins/iOS/Repro`
     - `Assets/Plugins/Android/Repro`
     - `Assets/Plugins/Android/libs/repro-android-sdk-x.x.x.aar`
     - `Assets/Plugins/Android/libs/kotlin-runtime-x.x.x.jar`
     - `Assets/Plugins/Android/libs/kotlin-stdlib-x.x.x.jar`
     - `Assets/Plugins/Android/libs/otto-x.x.x.jar`
     - `Assets/Plugins/Android/libs/aws-android-sdk-core-x.x.x.jar`
     - `Assets/Plugins/Android/libs/aws-android-sdk-s3-x.x.x.jar`
     - `Assets/Plugins/Android/libs/gson-x.x.x.jar`
2. 新しいSDKをインストールしてください。
   : - **Assets > Import Package > Custom Package...** を選択します
     - `Repro-unity5.unitypackage` をImportします

#### Unity 4

1. 下記を削除してください。
   : - `Assets/Editor/Repro`
     - `Assets/Plugins/Repro`
     - `Assets/Plugins/iOS/Repro`
     - `Assets/Plugins/Android/Repro`
2. 新しいSDKをインストールしてください。
   : - **Assets > Import Package > Custom Package...** を選択します
     - `Repro-unity4.unitypackage` をImportします

### 0.0.8 ~ 1.2.1からのアップグレード

1. 下記を削除してください。
   : - `Assets/Repro`
2. 新しいSDKをインストールしてください。
   : - **Assets > Import Package > Custom Package...** を選択します
     - Unity4の場合は `Repro-unity4.unitypackage` を、Unity5の場合は `Repro-unity5.unitypackage` をImportします

### 0.0.1 ~ 0.0.6からのアップグレード

1. 下記を削除してください。
   : - `Assets/Editor/Repro`
     - `Assets/Plugins/Repro`
     - `Assets/Plugins/iOS/Repro.embeddedframework`
     - `Assets/Plugins/iOS/ReproBridge.h`
     - `Assets/Plugins/iOS/ReproBridge.mm`
     - `Assets/Plugins/iOS/VERSION`
2. 新しいSDKをインストールしてください。
   : - **Assets > Import Package > Custom Package...** を選択します
     - Unity4の場合は `Repro-unity4.unitypackage` を、Unity5の場合は `Repro-unity5.unitypackage` をImportします

---

<script>
  window.location.href = "../remote-config.html";
</script>

---

## FCMへの移行手順: Unity

Googleからアナウンスされている通り、GCMは2019/4/11までに廃止が予定されております。すでにReproのプッシュ通知をGCMで実装している場合は、それまでに以下の手順を参照し、FCMでの実装に移行してください。

### 移行手順

#### Google Cloud PlatformのプロジェクトをFirebase Consoleへ移行する

Firebase ConsoleからGCMで利用していたプロジェクトを選択して作成してください：


* Google Cloud Platformのプロジェクト番号と、Firebase Consoleの送信者IDが同一であるか確認してください。Google Cloud Platformのプロジェクト番号は **Google Cloud Platform > IAMと管理 > 設定** のプロジェクト番号から確認できます：
  
* Firebase Consoleの送信者IDは **設定 > クラウドメッセージング** の送信者IDから確認できます：
  

#### FCMを設定する

1. [アプリの登録](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md#firebase-register-app) の手順を参照し、 `google-services.json` をダウンロードしてください。
2. [Firebaseの秘密鍵を生成](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md#firebase-generate-private-key) と [Firebaseの秘密鍵をReproに登録](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md#firebase-register-private-key) の手順を参照し、Firebaseの秘密鍵をReproに登録してください。

#### Repro Unity Packageのアップデート

[Unity Package 更新手順](https://docs.repro.io/ja/releases/sdk/unity/upgrade.md) に従って、Repro Unity Package 4.1.0以上にアップデートしてください。

#### Firebase SDKを導入する

##### GCMへの依存を削除する

`Assets/Plugins/Android/libs` に配置されている `play-services-gcm-x.x.x.aar` ファイルを削除してください。

##### FirebaseのUnity Packageをインポートする

[Firebaseの公式ドキュメント](https://firebase.google.com/docs/unity/setup?hl=ja) を参照し **FirebaseMessaging.unitypackage** をインポートしてください。

##### WARNING
Repro Unity Package 6.5.0 以下、あるいは Firebase Cloud Messaging for Unity 7.2.0 以下を使用される場合には **FirebaseInstanceId.unitypackage** を追加でインポートしてください。

##### WARNING
Firebaseのパッケージをインポートした後、 [導入時に修正したAndroidManifest.xml](https://docs.repro.io/ja/dev/sdk/getstarted/unity.md#unity-setup-application) がFirebaseの設定で上書きされることがあります。そのため、インポート後にもう一度 `AndroidManifest.xml` を修正してください。

#### AndroidManifest.xmlファイルを編集する

`io.repro.android.GCMReceiver` を `io.repro.ReproReceiver` に修正してください：

```diff
 <receiver
-    android:name="io.repro.android.GCMReceiver"
+    android:name="io.repro.android.ReproReceiver"
     android:exported="true"
     android:permission="com.google.android.c2dm.permission.SEND">
     <intent-filter>
         <action android:name="com.google.android.c2dm.intent.RECEIVE" />
         <category android:name="YOUR_PACKAGE_NAME" />
     </intent-filter>
 </receiver>
```

#### Registration IDの取得方法を変更する

FCMのRegistration IDは [こちら](https://firebase.google.com/docs/cloud-messaging/unity/client#initialize) の方法で取得可能です。取得したRegistration IDを `Repro.SetPushRegistrationID()` でセットしてください。また、 `Repro.enablePushNotification` の呼び出しの引数を削除してください。

```diff
 using UnityEngine;

 public class MyBehaviour : MonoBehaviour {

     void Start () {
         ...

 #if UNITY_ANDROID
-        Repro.EnablePushNotification(SENDER_ID);
+        Repro.EnablePushNotification();
+        Firebase.Messaging.FirebaseMessaging.TokenReceived += OnTokenReceived;
+        Firebase.Messaging.FirebaseMessaging.MessageReceived += OnMessageReceived;
 #endif

         ...
     }

+#if UNITY_ANDROID
+    public void OnTokenReceived(object sender, Firebase.Messaging.TokenReceivedEventArgs token) {
+        Repro.SetPushRegistrationID(token.Token);
+    }
+
+    public void OnMessageReceived(object sender, Firebase.Messaging.MessageReceivedEventArgs e) {
+        ...
+    }
+#endif
 }
```

---

## Cocos2d-x SDK リリースノート

* [Cocos2d-x SDK 更新手順](https://docs.repro.io/ja/releases/sdk/cocos2d-x/upgrade.md)
  * [iOS SDK 2.2.13以前に同梱されていたReproCpp.h/ReproCpp.mmをご利用の場合](https://docs.repro.io/ja/releases/sdk/cocos2d-x/upgrade.md#ios-sdk-2-2-13reprocpp-h-reprocpp-mm)



### 5.26.1 (2026/07/01)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.24.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-24-1)
  - [Android SDK 5.24.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-24-0)



### 5.26.0 (2026/05/26)

変更

- Cocos2d-x バージョン2系のサポートを追加しました。

  #### NOTE
  バージョン2系の動作は Cocos2d-x v2.2.3 環境において検証を行っています。



### 5.25.0 (2026/04/01)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [Android SDK 5.22.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-22-0)



### 5.24.0 (2026/03/05)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.23.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-23-0)
  - [Android SDK 5.21.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-21-0)



### 5.23.1 (2026/01/27)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.22.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-22-1)
  - [Android SDK 5.20.7](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-20-7)



### 5.23.0 (2025/12/15)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.22.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-22-0)



### 5.22.4 (2025/11/19)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [Android SDK 5.20.4](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-20-4)



### 5.22.3 (2025/11/14)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.21.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-21-1)
  - [Android SDK 5.20.3](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-20-3)



### 5.22.2 (2025/10/23)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [Android SDK 5.20.2](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-20-2)



### 5.22.1 (2025/09/29)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [Android SDK 5.20.1](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-20-1)



### 5.22.0 (2025/07/28)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.21.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-21-0)
  - [Android SDK 5.20.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-20-0)



### 5.21.0 (2025/04/25)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.20.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-20-0)
  - [Android SDK 5.19.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-19-0)



### 5.20.0 (2024/12/26)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.19.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-19-0)
  - [Android SDK 5.18.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-18-0)



### 5.19.1 (2024/10/30)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [Android SDK 5.17.1](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-17-1)



### 5.19.0 (2024/10/03)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.18.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-18-0)
  - [Android SDK 5.17.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-17-0)



### 5.18.0 (2024/07/11)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.17.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-17-0)
  - [Android SDK 5.16.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-16-0)



### 5.17.0 (2024/05/17)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.16.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-16-0)
  - [Android SDK 5.15.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-15-0)



### 5.16.0 (2024/04/30)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.15.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-15-0)
  - [Android SDK 5.14.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-14-0)



### 5.15.0 (2024/01/19)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.14.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-14-0)
  - [Android SDK 5.13.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-13-0)



### 5.14.1 (2023/12/22)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.13.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-13-1)



### 5.14.0 (2023/11/17)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.13.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-13-0)
  - [Android SDK 5.12.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-12-0)



### 5.13.0 (2023/10/16)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.12.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-12-0)
  - [Android SDK 5.11.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-11-0)



### 5.12.0 (2023/09/12)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.11.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-11-1)
  - [Android SDK 5.10.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-10-0)



### 5.11.0 (2023/06/13)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.11.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-11-0)
  - [Android SDK 5.9.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-9-0)



### 5.10.0 (2023/03/08)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.9.5](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-9-5)
  - [Android SDK 5.8.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-8-0)



### 5.9.3 (2023/02/14)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.9.4](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-9-4)



### 5.9.2 (2022/12/28)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.9.3](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-9-3)
  - [Android SDK 5.7.2](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-7-2)



### 5.9.1 (2022/10/05)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.9.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-9-1)
  - [Android SDK 5.7.1](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-7-1)



### 5.9.0 (2022/08/31)

新機能

- ユニバーサルリンク･アプリリンクに対応するためのコールバック処理の記述が可能になりました。
  - 詳細は [こちら](https://docs.repro.io/ja/dev/sdk/push-notification/cocos2d-x.md#universal-link-guide-cocos2d-x) をご覧ください。

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.9.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-9-0)
  - [Android SDK 5.7.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-7-0)

##### NOTE
Cocos2d-xをご利用の場合のみ、別途ブリッジ処理の実装が必要です。
実装方法の詳細については [ブリッジクラスの追加](https://docs.repro.io/ja/dev/sdk/getstarted/cocos2d-x.md#cocos2d-x-add-bridge-class) を参照してください。



### 5.8.0 (2022/04/14)

変更

- サポート品質の向上のため、クロスプラットフォーム環境におけるSDKの情報を取得する機能を追加しました。
- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.8.3](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-8-3)
  - [Android SDK 5.6.3](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-6-3)



### 5.7.0 (2021/12/07)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.8.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-8-0)
  - [Android SDK 5.6.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-6-0)



### 5.6.0 (2021/10/15)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.7.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-7-0)



### 5.5.0 (2021/08/03)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.6.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-6-0)
  - [Android SDK 5.5.1](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-5-1)



### 5.4.2 (2021/06/17)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.5.3](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-5-3)
  - [Android SDK 5.4.1](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-4-1)



### 5.4.0 (2021/06/04)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.5.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-5-1)
  - [Android SDK 5.4.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-4-0)



### 5.3.0 (2021/03/09)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.4.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-4-0)
  - [Android SDK 5.3.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-3-0)



### 5.2.0 (2021/02/09)

変更

- iOS 向け SDK の配布形式を `Repro.embeddedframework` から `Repro.framework` に変更しました。導入手順は [導入: Cocos2d-x](https://docs.repro.io/ja/dev/sdk/getstarted/cocos2d-x.md) をご覧ください。
- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.3.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-3-0)
  - [Android SDK 5.2.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-2-0)



### 5.1.1 (2021/01/25)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.2.12](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-2-12)
  - [Android SDK 5.1.12](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-1-12)



### 5.1.0 (2020/11/04)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.2.2](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-2-2)
  - [Android SDK 5.1.3](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-1-3)



### 5.0.0 (2020/08/28)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.1.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-1-0)
  - [Android SDK 5.1.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-1-0)
- AIレコメンド・アプリ内メッセージ連携機能（クローズドβ）に関するAPIを追加しました。
- ニュースフィード機能に関するAPIを追加しました。
  - 詳細は [こちら](https://docs.repro.io/ja/dev/sdk/newsfeed.md) をご覧ください。
- UXオプティマイザー機能（クローズドβ）に関するAPIを追加しました。
  - 詳細は [こちら](https://docs.repro.io/ja/dev/sdk/remote-config/cocos2d-x.md) をご覧ください。



### 4.1.0 (2020/05/14)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 4.7.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-4-7-1)
  - [Android SDK 4.4.1](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-4-4-1)

### 4.0.0  (2019/10/29)

変更


- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 4.3.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-4-3-0)
  - [Android SDK 4.2.1](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-4-2-1)
- 動画機能に関する以下のAPIを削除しました。
  - `startRecording`
  - `stopRecording`
  - `pauseRecording`
  - `resumeRecording`
  - `maskWithRect`
  - `unmaskWithRect`
- 動画機能に関する詳細は、以下のリンク先をご確認ください。
  - [iOS SDK 3.2.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-3-2-0)
  - [Android SDK 3.3.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-3-3-0)



### 3.3.0  (2019/04/05)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 3.3.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-3-3-0)



### 3.2.2 (2019/03/14)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 3.2.2](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-3-2-2)
- オプトアウト機能用のAPIを追加しました。
  - 詳細は [こちら](https://docs.repro.io/ja/dev/sdk/optout/index.md) をご覧ください。



### 3.2.0 (2019/02/15)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 3.2.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-3-2-0)
  - [Android SDK 3.3.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-3-3-0)
- 動画機能に関する主要なコードを削除し、動画機能が動作しないようにしました。以下のAPIを呼び出しても問題ありませんが何も実行されません。
  - `startRecording`
  - `stopRecording`
  - `pauseRecording`
  - `resumeRecording`
  - `maskWithRect`
  - `unmaskWithRect`

  #### WARNING
  録画関連APIは削除されました。2019年5月22日現在、これを利用することはできません。



### 3.1.0 (2018/11/14)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 3.0.4](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-3-0-4)
  - [Android SDK 3.1.1](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-3-1-1)
- GCMのサポートを廃止しました。
  - GCMをご利用中の場合はFCMへの移行が必要となります。移行手順は [FCMへの移行手順: Cocos2d-x](https://docs.repro.io/ja/releases/migration-to-fcm/cocos2d-x.md) をご覧ください。
- プッシュ通知をご利用いただくには、firebase-messaging バージョン17.1.0以降が必須となりました。
  - 現在 firebase-messaging バージョン17.1.0未満をご利用中の場合は、17.1.0以降に変更してください。
  - また、プッシュ通知の実装で `Repro.enablePushNotification()` の呼び出しが必須となりました。詳細は [プッシュ通知 (Cocos2d-x)](https://docs.repro.io/ja/dev/sdk/push-notification/cocos2d-x.md) をご覧ください。
- 標準イベントをトラックするためのAPIを追加しました。詳細は [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md) を参照してください。

##### NOTE
iPhone 7以降かつiOS12以上の端末では録画機能が無効となります。

**録画機能を無効とする背景**

iOS12の不具合の影響で、iPhone 7以降かつiOS12以上の端末で録画機能を利用すると、端末の負荷が増大するという現象が発生します。この現象を回避するため、録画機能を無効としています。また [iOS SDK 3.0.3](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-3-0-3) にて暫定的に録画可能としましたが、この暫定措置ではCocos2d-xアプリの画面が録画できません。

**今後の見通し**

AppleにはiOS12の不具合を報告済みです。Apple側の修正が完了次第、iPhone 7以降かつiOS12以上の端末でも録画可能となるSDKのリリースを検討します。



### 3.0.0 (2018/08/27)

変更

SDKを更新しました。

- [iOS SDK 3.0.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-3-0-0)
- [Android SDK 3.0.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-3-0-0)

データアップロードの処理を変更しました。

- Cocos2d-x SDK 3.0.0未満は、2019年6月24日以降にセッションデータをアップロードできなくなります。
- そのため、2019年6月24日までにCocos2d-x SDK 3.0.0以上にアップデートしてください。



### 2.13.0 (2018/08/16)

変更

SDKを更新しました。

- [iOS SDK 2.13.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-2-13-0)
- [Android SDK 2.13.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-2-13-0)



### 2.0.1 (2018/02/20)

変更

- 起動時の通信先のURLを変更しました。
  - アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。
  - 詳細は [こちら](https://docs.repro.io/ja/releases/change-domain/index.md) をごらんください。

Cocos2d-x SDKに同梱されているiOS SDKおよびAndroid SDKのバージョン

- [iOS SDK 2.2.18](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-2-2-18)
- [Android SDK 2.3.17](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-2-3-17)



### 2.0.0 (2017/04/11)

新機能

- Android をサポートしました。

Cocos2d-x SDKに同梱されているiOS SDKおよびAndroid SDKのバージョン

- [iOS SDK 2.2.13](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-2-2-13)
- [Android SDK 2.3.9](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-2-3-9)

---

## Cocos2d-x SDK 更新手順

### iOS SDK 2.2.13以前に同梱されていたReproCpp.h/ReproCpp.mmをご利用の場合

#### 古いSDKを削除する

Xcodeプロジェクトから `ReproCpp.h/ReproCpp.mm` および `Repro.embeddedframework` を削除してください。



#### 新しいSDKをインストールする

[導入: Cocos2d-x](https://docs.repro.io/ja/dev/sdk/getstarted/cocos2d-x.md) に従いRepro Cocos2d-x SDKを導入してください。

---

cpp

## 導入: Cocos2d-x



### Repro Cocos2d-x SDKのインストール

- [こちら](https://github.com/reproio/repro-cocos2dx-sdk) から最新版の Repro Cocos2d-x SDK のzipファイルをダウンロードしてください。
- ダウンロードしたファイルに含まれる `Reproディレクトリ` をCocos2d-xのプロジェクトディレクトリ直下にコピーしてください。
  - `Reproディレクトリ` の中のファイルは後ほどiOSプロジェクトおよびAndroidプロジェクトに追加します



### iOSプロジェクトへの導入

#### Xcodeプロジェクトへのブリッジクラスの追加

Xcode プロジェクトを開き、先ほどコピーした `Reproディレクトリ` 内のファイルを追加します。

- `File > Add Files To "YOUR PROJECT NAME" ...` を選択
- 以下のファイルを選択する
  - `ReproCpp.h`
  - `ReproCpp.mm`
  - `ReproCppConfig.h`
  - `ReproConverterIOS.h`
  - `ReproConverterIOS.mm`
  - `Properties/`
  - `NewsFeed/NewsFeedEntry.mm`
  - `RemoteConfig/RemoteConfig.mm`
- 追加時のオプションを以下の通りとする
  - `Destination: Copy items if needed` -> off
  - `Added folders:` -> Create groups
  - `Add to targets:` -> アプリケーションのTargetを選択してください



#### Xcode プロジェクトへのフレームワークの追加

ダウンロードしたzipファイルに含まれる `Repro.xcframework` を追加します。

- `File > Add Files To "YOUR PROJECT NAME" ...` を選択
- ダウンロードしたzipファイルに含まれる `Repro.xcframework` を選択
- 追加時のオプションを以下の通りとする
  - `Destination: Copy items if needed` -> on
  - `Added folders:` -> Create groups
  - `Add to targets:` -> アプリケーションのTargetを選択してください



さらに、以下のフレームワークを追加してください。

プロジェクトの **Targets > Build Phases > Link Binary With Libraries** にて追加してください。

- **SystemConfiguration.framework**
- **WebKit.framework**
- **UserNotifications.framework**



### Androidプロジェクトへの導入

##### NOTE
AndroidプロジェクトにRepro SDKを導入する場合は、Cocos2d-x v3.10以上およびAndroid Studioを推奨しております。推奨環境以外では、導入にあたって一部のコードや手順が異なる場合がございますのでご了承ください。

#### SDKのインストール

`proj.android-studio/app` ディレクトリ内に `libs` ディレクトリを作成してください。

上記で作成した `libs` ディレクトリの中にダウンロードしたファイルに含まれる `repro-android-sdk-x.x.x.aar` をコピーしてください。

次に `app/build.gradle` に以下のコードを追加してください。

```groovy
repositories {
    flatDir { dirs 'libs' }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation project(':libcocos2dx')
    implementation(name: 'repro-android-sdk-x.x.x', ext:'aar')
}
```

##### NOTE
Gradle 3.4 未満のバージョンの場合は 'implementation' が利用できません。
'compile'を利用してください。

**独自のApplicationクラスを使っていない場合:**

`AndroidManifest.xml` を開いて **application** エレメントの **android:name** 属性に **io.repro.android.Cocos2dxApplication** を指定してください。

```xml
 <!-- AndroidManifest.xml -->
  <application
      android:name="io.repro.android.Cocos2dxApplication"
      android:label="@string/app_name"
      android:allowBackup="true"
      android:icon="@mipmap/ic_launcher">
```

**独自のApplicationクラスを使っている場合:**

独自のApplicationクラスの `onCreate` にて `io.repro.android.Cocos2dxBridge.setupWithoutToken(Application)` を呼び出してください。

```diff
 public class MyApplication extends Application {
     @Override
     public void onCreate() {
         super.onCreate();
           ...
+        io.repro.android.Cocos2dxBridge.setupWithoutToken(this);
         ...
     }
 }
```

なお、Repro SDKを使用するにはアプリケーションに以下のパーミッションが必要です。これらのパーミッションはAndroid Studioの「Manifest Merging」機能によって自動で追加されるため、`AndroidManifest.xml` に手動で追加する必要はありません。

* `android.permission.INTERNET`
* `android.permission.ACCESS_NETWORK_STATE`



#### ブリッジクラスの追加

`app/jni/Android.mk` の `LOCAL_SRC_FILES` と `LOCAL_C_INCLUDES` を以下のように編集してください。

```sh
   // Android.mk
   LOCAL_SRC_FILES := hellocpp/main.cpp \
                      ../../../Classes/AppDelegate.cpp \
                      ../../../Classes/HelloWorldScene.cpp \
                      ../../../Repro/ReproCpp.cpp \
                      ../../../Repro/ReproConverterAndroid.cpp \
                      ../../../Repro/NewsFeed/NewsFeedEntry.cpp \
                      ../../../Repro/RemoteConfig/RemoteConfig.cpp \
                      ../../../Repro/Properties/StandardEventProperties.cpp \
                      ../../../Repro/Properties/ViewContentProperties.cpp \
                      ../../../Repro/Properties/SearchProperties.cpp \
                      ../../../Repro/Properties/AddToCartProperties.cpp \
                      ../../../Repro/Properties/AddToWishlistProperties.cpp \
                      ../../../Repro/Properties/InitiateCheckoutProperties.cpp \
                      ../../../Repro/Properties/AddPaymentInfoProperties.cpp \
                      ../../../Repro/Properties/PurchaseProperties.cpp \
                      ../../../Repro/Properties/ShareProperties.cpp \
                      ../../../Repro/Properties/LeadProperties.cpp \
                      ../../../Repro/Properties/CompleteRegistrationProperties.cpp

   LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../../Classes
   LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../Repro
   LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../Repro/Properties
```

`app/src` 以下に下記のクラスを追加してください。

```Java
package com.your.PackageName;
import org.cocos2dx.lib.Cocos2dxHelper;
import io.repro.android.Repro;
import io.repro.android.remoteconfig.RemoteConfigListener;
import android.net.Uri;

public class ReproBridge {
    public static void enableInAppMessagesOnForegroundTransition() {
        Repro.enableInAppMessagesOnForegroundTransition(getActivity());
    }

    private static native void nativeListenerHandler(final RemoteConfigListener.FetchStatus status);

    public static void fetchRemoteConfig(final long timeout) {
        Repro.getRemoteConfig().fetch(timeout, new RemoteConfigListener() {
            @Override
            public void onCompletion(FetchStatus status) {
                ReproBridge.nativeListenerHandler(status);
            }
        });
    }

    private static native void nativeOpenUrlHandler(final String url);

    public static void setupOpenUrlCallback() {
        Repro.setOpenUrlCallback(new Repro.OpenUrlCallback() {
            @Override
            public void onOpened(Uri uri) {
                ReproBridge.nativeOpenUrlHandler(uri.toString());
            }
        });
    }

    public static Activity getActivity() {
        Activity activity = null;

        try {
            Class<?> helperClass = Class.forName("org.cocos2dx.lib.Cocos2dxHelper");
            java.lang.reflect.Method getActivityMethod = helperClass.getMethod("getActivity");
            activity = (Activity) getActivityMethod.invoke(null);
        } catch (Exception e) {
            activity = getActivityForCocosV2();
        }
        return activity;
    }

    private static Activity getActivityForCocosV2() {
        Context context = Cocos2dxActivity.getContext();
        if (context instanceof Activity) {
            return (Activity) context;
        }
        return null;
    }
}
```

[Repro SDKの導入](#cocos2dx-setup) にて追加した `Repro/ReproCppConfig.h` の以下の箇所を編集してください。

```Objc
   #ifndef __REPRO_CPP_CONFIG_H__
   #define __REPRO_CPP_CONFIG_H__

   #if COCOS2D_VERSION >= 0x00030000
   #define CLASS_NAME_REPRO_CLIENT_BRIDGE  "com.your.PackageName.ReproBridge"
   #else
   #define CLASS_NAME_REPRO_CLIENT_BRIDGE  "com/your/PackageName/ReproBridge"
   #endif

   #define JNI_REPRO_CLIENT_BRIDGE         com_your_PackageName_ReproBridge

   #endif
```

### セットアップ

`AppDelegate.cpp` で `ReproCpp.h` をインクルードし、 `applicationDidFinishLaunching` で [セッション](https://docs.repro.io/ja/dev/sdk/session.md) を開始してください。

`YOUR_APP_TOKEN` には管理画面の **設定 > プロジェクト設定 > 認証情報** に記載されている **SDK トークン** を設定してください。

```c++
#include "ReproCpp.h"

...

bool AppDelegate::applicationDidFinishLaunching() {

  ...

  // Setup Repro
  ReproCpp::setup("YOUR_APP_TOKEN");

  ...
}
```

SDKが収集した情報は定期的にサーバーにアップロードされます。

### イベントをトラックする

意味のある分析や、マーケティング施策を実施するためには、適切なユーザーグループを絞り込むことが重要です。イベントをトラックしてユーザーの行動を記録することにより、管理画面上で目的に応じた適切なユーザーグループを選択することができるようになります。

イベントを用いたユーザーグループ指定の例:

- [キャンペーンの作成画面で、イベントやユーザープロフィールを組み合わせて、配信対象となるユーザーグループを指定する](https://docs.repro.io/ja/dashboard/campaign/target.md)

どういうイベントをとるべきかわからない場合は、まず各画面の表示時にイベントをとってみることをおすすめします。

例:

```objc
@implementation MainViewController

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [Repro track:@"MainViewController" properties:nil];

    ...
}
```

```swift
class MainViewController: UIViewController {

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        Repro.track(event: "MainViewController", properties: [:])

        ...
    }
```

```java
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onResume() {
        super.onResume();
        Repro.track("MainActivity");

        ...
    }
}
```

```kotlin
class MainActivity : AppCompatActivity() {

    override fun onResume() {
        super.onResume()
        Repro.track("MainActivity")

        ...
    }
}
```

```cpp
#include "ReproCpp.h"

...

ReproCpp::track("Initialized");
```

```csharp
Repro.Track ("Initialized");
```

```js-cordova
// Will be written later
```

```js-react-native
class MainScreen extends React.Component {

    componentDidMount() {
        Repro.track("MainScreen", {});
    }

    ...
 }
```

```js-expo
import Repro from 'react-native-repro';

...

Repro.track("MainScreen", {});
```

```dart
import 'package:repro_flutter/repro.dart';

...

await Repro.track("Initialized");
```

### ユーザーIDをセットする

Repro では分析結果はユーザー単位で集計しています。ユーザーIDをセットすることにより、下記のメリットがあります:

- 複数のデバイスを使っているユーザーを同一視できる
- キャンペーンの配信対象の抽出がより精緻になる

詳しくは [こちら](https://docs.repro.io/ja/dev/sdk/user-id.md) をご覧ください。

### プッシュ通知を配信する

Reproでは、管理画面もしくはAPIからプッシュ通知配信をすることができます。プッシュ通知配信をするための実装は [こちら](https://docs.repro.io/ja/dev/sdk/push-notification/index.md) をご覧ください。

### Next...

その他の機能についての詳細は、以下をご覧ください。

- [セッション・ライフサイクル](https://docs.repro.io/ja/dev/sdk/session.md)
- [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md)
- [ユーザーID](https://docs.repro.io/ja/dev/sdk/user-id.md)
- [デバイスID](https://docs.repro.io/ja/dev/sdk/device-id.md)
- [ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md)
- [WebView](https://docs.repro.io/ja/dev/sdk/webview.md)
- [オプトアウト機能](https://docs.repro.io/ja/dev/sdk/optout/index.md)
- [アプリ内メッセージ](https://docs.repro.io/ja/dev/sdk/in-app-message.md)
- [プッシュ通知](https://docs.repro.io/ja/dev/sdk/push-notification/index.md)
- [Adjustで取得したアトリビューションデータをReproにセットする](https://docs.repro.io/ja/dev/sdk/integrate-adjust.md)
- [AppsFlyerで取得したアトリビューションデータをReproにセットする](https://docs.repro.io/ja/dev/sdk/integrate-appsflyer.md)

---

cpp

## プッシュ通知 (Cocos2d-x)

### プッシュ通知の設定

[APNs証明書の設定 (iOS)](https://docs.repro.io/ja/dev/sdk/push-notification/setup-ios.md) と [FCMの設定 (Android)](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md) を参照し、設定してください。

### Firebase C++ SDKを導入する

[Firebaseの公式ドキュメント](https://firebase.google.com/docs/cpp/setup?hl=ja) を参照し、 **libfirebase_app.a** と **libfirebase_messaging.a** を導入してください。なお、Firebase C++ SDKはAndroidアプリで利用するものであり、iOSアプリでは利用しません。

### iOSプロジェクトの実装

#### Capabilitiesの設定

XcodeのCapabilitiesにてPush NotificationsをONにします。



#### APNsへの端末の登録

プッシュ通知を受信するために、アプリ起動時にAPNsへの端末登録処理を実装します。

**Target > Build Pahses > Link Binary With Libraries** から **UserNotifications.framework** を追加します。



次に `AppController.mm` に下記のコードを追加してください。

```objc
// AppController.mm
#import <Repro/Repro.h>
#import <UserNotifications/UserNotifications.h>

// Conforms AppController class to UNUserNotificationCenterDelegate protocol
@interface AppController() <UNUserNotificationCenterDelegate>
@end

@implementation AppController

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    ...

    if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_9_x_Max) {
        UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
        center.delegate = self;
        [center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionBadge | UNAuthorizationOptionSound) completionHandler:^(BOOL granted, NSError * _Nullable error) {
        }];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    } else {
        UIUserNotificationType types = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    }

    return YES;
}
```

#### デバイストークンをReproに送信

プッシュ通知の宛先を指定するためにデバイストークンをReproに送信します。

デバイストークンの取得に成功した場合は `application:didRegisterForRemoteNotificationsWithDeviceToken:` メソッドが呼び出されるので、その中でReproにデバイストークンを渡します。

デバイストークンの取得に失敗した場合は `application:didFailToRegisterForRemoteNotificationsWithError:` メソッドが呼び出されるので、エラーの内容を見て適宜対処します。

```objc
    // AppController.mm
    - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
    {
        [Repro setPushDeviceToken:deviceToken];
    }

    - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
    {
        NSLog(@"Remote Notification Error: %@", error);
    }
```

### Androidプロジェクトの実装

#### `AndroidManifest.xml` ファイルを編集する

##### Receiverの登録

以下のXML中の "YOUR_PACKAGE_NAME" をアプリケーションのパッケージ名に置き換え、AndroidManifest.xmlの `<application>` タグの中に追加してください。

```xml
<receiver
    android:name="io.repro.android.ReproReceiver"
    android:exported="true"
    android:permission="com.google.android.c2dm.permission.SEND">
    <intent-filter>
        <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        <category android:name="YOUR_PACKAGE_NAME" />
    </intent-filter>
</receiver>
```

##### 通知チャンネルの設定

Android Oにて、ユーザーが通知を管理できるように通知チャンネルが導入されました。

Repro SDKで利用する通知チャンネルの設定を行うには、「ID」「名前」「ユーザー向けの説明」「badgeの表示有無」を指定する必要があります。
以下のXML中の `value`, `resource` を設定したい値に書き換え、AndroidManifest.xmlの `<application>` タグの中に追加してください。
IDと名前の指定は必須、その他は省略可能です。「ユーザー向けの説明」省略時は空文字列、「badgeの表示有無」省略時はbadgeの表示有りとなります。

##### WARNING
- アプリのtargetSDKVersionが26以上かつAndroid O以降の機種で動作させる場合、IDと名前が指定されていなければSDKはReproからのプッシュ通知を表示いたしませんのでご注意ください。
- `ChannelId` に指定する値は、整数や小数ではなく `test ID` のような文字列を指定してください。文字列以外の値を指定するとチャンネルIDの指定がうまく動作せず、プッシュ通知が表示されません。
- `ChannelName` と `ChannelDescription` の設定は `android:resource` 属性を使用してください。

```xml
<meta-data
    android:name="io.repro.android.PushNotification.ChannelId"
    android:value="YOUR_CHANNEL_ID">
</meta-data>

<meta-data
    android:name="io.repro.android.PushNotification.ChannelName"
    android:resource="@string/YOUR_CHANNEL_NAME">
</meta-data>

<meta-data
    android:name="io.repro.android.PushNotification.ChannelDescription"
    android:resource="@string/YOUR_CHANNEL_DESCRIPTION">
</meta-data>

<meta-data
    android:name="io.repro.android.PushNotification.ShowBadge"
    android:value="true">
</meta-data>
```

指定されたIDの通知チャンネルが存在しない場合はAndroidManifest.xmlの指定を基にSDKが自動で作成し、指定されたIDの通知チャンネルが存在する場合は既存のものを利用します。

既存のものを利用する場合、SDKは「名前」、「ユーザー向けの説明」及び「チャンネルの重要度」を更新します。

また、アプリのtargetSDKVersionが25以下の場合、あるいは、Android O未満の機種の場合は、SDKは上記の通知チャンネルに関する設定を無視します。

##### NOTE
通知チャンネルはAndroid Oで導入されたAndroidの標準機能です。通知チャンネルの詳細は [こちら](https://developer.android.com/preview/features/notification-channels.html?hl=ja) をご覧ください。

##### アイコンと背景色のカスタマイズ

Android5.0以降の機種で、通知エリアに表示されるアイコンとその背景色をカスタマイズする場合は、以下のXMLをAndroidManifest.xmlの `<application>` タグの中に追加してください。Android5.0未満の機種では以下の設定は無視され、通知エリアにはアプリケーションのアイコンおよびシステムデフォルトの背景色が使用されます。

```xml
<meta-data
    android:name="io.repro.android.PushNotification.SmallIcon"
    android:resource="@drawable/YOUR_ICON_ID">
</meta-data>

<meta-data
    android:name="io.repro.android.PushNotification.AccentColor"
    android:resource="@color/YOUR_COLOR_ID">
</meta-data>
```

#### Registration IDをReproに送信

`AppActivity` の `onCreate(Bundle savedInstanceState)` 内にて `enablePushNotification()` を呼び出します。

```Java
    // AppActivity.java
    package org.cocos2dx.cpp;

    import android.os.Bundle;
    import org.cocos2dx.lib.Cocos2dxActivity;
    import io.repro.android.Repro;

    public class AppActivity extends Cocos2dxActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            Repro.enablePushNotification();
        }
    }
```

次に、`firebase::messaging::Listener` interfaceを実装したクラスの [OnTokenReceived](https://firebase.google.com/docs/reference/cpp/class/firebase/messaging/listener#ontokenreceived) メソッドにて、`ReproCpp::setPushRegistrationID` を呼び出してください。

```CPP
#include "ReproCpp.h"

...

class MyFirebaseMessagingListener : public firebase::messaging::Listener {
...
public:
    void OnTokenReceived(const char* token) override {
        ReproCpp::setPushRegistrationID(token);
    }
```

上記の実装が終わったら、 [プッシュ通知作成画面](https://docs.repro.io/ja/dashboard/campaign/push-notification.md#push-create-message) をご覧ください。

#### プッシュ通知受信時の動作をカスタマイズする

Repro Cocos2d-x SDKは [オプション：プッシュ通知受信時の動作をカスタマイズする](android.html#customize-receiver) に示すプッシュ通知受信時の動作のカスタマイズには対応しておりません。ご了承ください。



### オプション：ユニバーサルリンク/アプリリンクを使用する



端末に表示されたプッシュ通知およびアプリ内メッセージに設定されたリンクをタップした際に実行されるURLには、ユニバーサルリンク（またはアプリリンクと呼ばれる）を指定することが可能です。
（簡単のため、以下ではこれらをユニバーサルリンクと呼びます）

アプリにてユニバーサルリンクの実行時の処理を追加するには、以下の通り実装を行う必要があります。
（ここで設定された動作は、プッシュ通知およびアプリ内メッセージ対し有効となります。）

#### ユニバーサルリンクのURLパターンを登録する

ユニバーサルリンクを利用するためには、まずユニバーサルリンクのURLのパターン（正規表現）を指定する必要があります。

##### NOTE
パターン（正規表現）に合致すると、プッシュ通知の開封時や、アプリ内メッセージの遷移先に設定されたURLに対して、後述のコールバック処理をキックします。

また、アプリ内メッセージでHTMLコンテンツを表示するとき、そのコンテンツ内で発生したリクエストに対してもユニバーサルリンクの判定が行われます。

この指定は、iOSの場合は `AppDelegate` または `.plist` ファイル、Androidの場合は `Application` 継承クラス または `AndroidManifest.xml` ファイルのどちらか一方に記述することで行うことができます。

```objc
// AppDelegate.m

#import <Repro/Repro.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [Repro addOpenUrlFilterRegEx:@"https://example\\.com/page/"];
    [Repro addOpenUrlFilterRegEx:@"your-domain\\.com/.+\?universal=true"];
    ...
}


// .plist file
/*
<dict>
    <key>RPROpenUrlFilterRegExList</key>
    <array>
        <string>https://example\.com/page/</string>
        <string>your-domain\.com/.+\?universal=true</string>
    </array>
    ...
</dict>
*/
```

```java
// MyApplication.java

import io.repro.android.Repro;

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        Repro.addOpenUrlFilterRegEx("https://example\\.com/page/");
        Repro.addOpenUrlFilterRegEx("your-domain\\.com/.+\\?universal=true");
        ...
    }
...
}


// AndroidManifest.xml
// To specify multiple URL patterns, enter them separated by commas.
<application>
    ...
    <meta-data
        android:name="io.repro.android.OpenUrlFilterRegExList"
        android:value="https://example\\.com/page/;your-domain\\.com/.+\\?universal=true">
    </meta-data>
</application>
```

```kotlin
// MyApplication.kt

import io.repro.android.Repro

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        Repro.addOpenUrlFilterRegEx("https://example\\.com/page/")
        Repro.addOpenUrlFilterRegEx("your-domain\\.com/.+\\?universal=true")
        ...
    }
    ...
}


// AndroidManifest.xml
// To specify multiple URL patterns, enter them separated by commas.
<application>
    ...
    <meta-data
        android:name="io.repro.android.OpenUrlFilterRegExList"
        android:value="https://example\\.com/page/;your-domain\\.com/.+\\?universal=true">
    </meta-data>
</application>
```

```swift
// AppDelegate.swift

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
{
    Repro.add(openUrlFilterRegEx: "https://example\\.com/page/")
    Repro.add(openUrlFilterRegEx: "your-domain\\.com/.+\\?universal=true")
    ...
}

// .plist file
/*
<dict>
    <key>RPROpenUrlFilterRegExList</key>
    <array>
        <string>https://example\.com/page/</string>
        <string>your-domain\.com/.+\?universal=true</string>
    </array>
    ...
</dict>
*/
```

```dart
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

```csharp
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

```cpp
// YourAppNameScene.cpp

bool YourAppName::init() {
    ReproCpp::addOpenUrlFilterRegEx("https://example\\.com/page/");
    ReproCpp::addOpenUrlFilterRegEx("your-domain\\.com/.+\\?universal=true");
    ...
}
```

```js-cordova
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

```js-react-native
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

##### WARNING
ユニバーサルリンクとして設定するURLパターンは、可能な限り **ドメインとパスまで含めて具体的に指定** し、 **全て小文字で指定** してください。

もし、 https のようにスキームのみを指定した場合、アプリ内メッセージで表示された画面内で実行されたスクリプトなどによるリクエストもユニバーサルリンクと誤って判定され、意図しないタイミングでコールバック処理が実行される可能性があります。

また、URLパターンのスキーム/ドメイン部分に大文字を使用した場合、HTMLアプリ内メッセージで表示したボタンからユニバーサルリンクを使って遷移させようとするときに、スキーム/ドメイン部分が自動的に小文字に変換されて処理されます。パターン（正規表現）に一致せず、意図したタイミングでコールバック処理が実行されない可能性があります。

#### ユニバーサルリンク実行時の処理を登録する

次に、ユニバーサルリンクが実行された際に動作するコールバック処理を実装します。
処理内には、例えばURLのパターンに応じて画面遷移を行う動作などを記述します。

```objc
#import <Repro/Repro.h>

...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [Repro setOpenUrlCallback:^(NSURL *url) {
        if ([url.host isEqualToString:@"example.com"]) {
            // In case of your universal link perform navigation, present content, ...
            handleUniversalLink(url);
        }
    }];

    ...
    [Repro setup:@"YOUR_APP_TOKEN"];
    ...
}
```

```swift
// Set a callback that is executed everytime an URL is about to be opened
Repro.setOpenUrlCallback { url in
    if url.host == "example.com" {
        // In case of your universal link perform navigation, present content, ...
        handleUniversalLink(url)
    }
}
...
Repro.setup(token: "YOUR_APP_TOKEN")
...
```

```java
import io.repro.android.Repro;

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        // In order to execute a callback when a push notification is tapped,
        // the callback must be set in Application, not Activity.
        Repro.setOpenUrlCallback(new Repro.OpenUrlCallback() {
            // ** This callback method is executed in the main thread **
            @Override
            public void onOpened(Uri uri) {
                if ("example.com".equals(uri.getHost())) {
                    // In case of your universal link perform navigation, present content, ...
                }
            }
        });

        ...
        Repro.setup(this, YOUR_APP_TOKEN);
        ...
    }
    ...
}
```

```kotlin
import io.repro.android.Repro

class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        // In order to execute a callback when a push notification is tapped,
        // the callback must be set in Application, not Activity.
        Repro.setOpenUrlCallback { uri ->
            // ** This callback method is executed in the main thread **
            if (uri.host == "example.com") {
                // In case of your universal link perform navigation, present content, ...
            }
        }

        ...
        Repro.setup(this, "YOUR_APP_TOKEN")
        ...
    }
    ...
}
```

```dart
Repro.setOpenUrlCallback((uri) { // uri is of type Uri
   debugPrint("Universal Link Callback Handler received: " + uri.toString());
});
```

```csharp
// Somewhere before Repro.Setup(...)
Repro.SetOpenUrlCallback(uri => // uri is of type Uri
{
    Debug.Log("Universal Link Callback Handler received: " + uri.ToString());
});
```

```cpp
bool YourAppName::init() {
    ReproCpp::addOpenUrlFilterRegEx(...);

    ReproCpp::setOpenUrlCallback([](const char *url) {
        if (strcmp(url, "example.com") == 0) {
            // In case of your universal link perform navigation, present content, ...
        }
    });

    ReproCpp::setup("YOUR_APP_TOKEN")
    ...
}
```

```js-cordova
Repro.setOpenUrlCallback(function(url) { // url is of type String
    alert('Universal Link Callback Handler received: ' + url);
    if (url.includes("http://example.org")) {
        // In case of your universal link perform navigation, present content, ...
    }
});
```

```js-react-native
Repro.setOpenUrlCallback( (url) => {  // url is of type String
    console.log('Universal Link Callback Handler received: ' + url);
    if (url.includes("http://example.org")) {
        // In case of your universal link perform navigation, present content, ...
    }
});
```

#### ブリッジ処理を実装する

最後に、コールバックの実行に必要なブリッジ処理を実装します。
実装方法の詳細は [ブリッジクラスの追加](https://docs.repro.io/ja/dev/sdk/getstarted/cocos2d-x.md#cocos2d-x-add-bridge-class) を参照してください。

---

<script>
  window.location.href = "../remote-config.html";
</script>

---

## FCMへの移行手順: Cocos2d-x

Googleからアナウンスされている通り、GCMは2019/4/11までに廃止が予定されております。すでにReproのプッシュ通知をGCMで実装している場合は、それまでに以下の手順を参照し、FCMでの実装に移行してください。

### 移行手順

#### Google Cloud PlatformのプロジェクトをFirebase Consoleへ移行する

Firebase ConsoleからGCMで利用していたプロジェクトを選択して作成してください：


* Google Cloud Platformのプロジェクト番号と、Firebase Consoleの送信者IDが同一であるか確認してください。Google Cloud Platformのプロジェクト番号は **Google Cloud Platform > IAMと管理 > 設定** のプロジェクト番号から確認できます：
  
* Firebase Consoleの送信者IDは **設定 > クラウドメッセージング** の送信者IDから確認できます：
  

#### FCMを設定する

1. [アプリの登録](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md#firebase-register-app) の手順を参照し、 `google-services.json` をダウンロードしてください。
2. [Firebaseの秘密鍵を生成](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md#firebase-generate-private-key) と [Firebaseの秘密鍵をReproに登録](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md#firebase-register-private-key) の手順を参照し、Firebaseの秘密鍵をReproに登録してください。

#### Repro Cocos2d-x SDKのアップデート

[Cocos2d-x SDK 更新手順](https://docs.repro.io/ja/releases/sdk/cocos2d-x/upgrade.md) に従って、Repro Cocos2d-x SDK 3.1.0以上にアップデートしてください。

#### Firebase SDKを導入する

##### GCMへの依存を削除する

```diff
 dependencies {
-     implementation "com.google.android.gms:play-services-gcm:15.0.1"
 }
```

##### Firebase C++ SDKを導入する

[Firebaseの公式ドキュメント](https://firebase.google.com/docs/cpp/setup?hl=ja) を参照し、 **libfirebase_app.a** と **libfirebase_messaging.a** を導入してください。

#### AndroidManifest.xmlファイルを編集する

`io.repro.android.GCMReceiver` を `io.repro.ReproReceiver` に修正してください：

```diff
 <receiver
-    android:name="io.repro.android.GCMReceiver"
+    android:name="io.repro.android.ReproReceiver"
     android:exported="true"
     android:permission="com.google.android.c2dm.permission.SEND">
     <intent-filter>
         <action android:name="com.google.android.c2dm.intent.RECEIVE" />
         <category android:name="YOUR_PACKAGE_NAME" />
     </intent-filter>
 </receiver>
```

#### Registration IDの取得方法を変更する

`Repro.enablePushNotification` の呼び出しの引数を削除してください。

```diff
 // AppActivity.java
 package org.cocos2dx.cpp;

 import android.os.Bundle;
 import org.cocos2dx.lib.Cocos2dxActivity;
 import io.repro.android.Repro;

 public class AppActivity extends Cocos2dxActivity {
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        Repro.enablePushNotification();
-        Repro.enablePushNotification("SENDER_ID");
     }
 }
```

次に、`firebase::messaging::Listener` interfaceを実装したクラスの [OnTokenReceived](https://firebase.google.com/docs/reference/cpp/class/firebase/messaging/listener#ontokenreceived) メソッドにて、`ReproCpp::setPushRegistrationID` を呼び出してください。

```CPP
#include "ReproCpp.h"

...

class MyFirebaseMessagingListener : public firebase::messaging::Listener {
...
public:
    void OnTokenReceived(const char* token) override {
        ReproCpp::setPushRegistrationID(token);
    }
```

---

## バックポート版への更新手順: iOS

2018年2月20日時点でサポートしているSDKのすべてのマイナーバージョンごとに、起動時の通信先のURLのみを変更したバックポート版をリリースしました。ご利用中のSDKバージョンのマイナーバージョン(バージョン番号の2桁目)を確認し、最も近いバージョンへ更新してください。

### バックポート版のiOS SDKバージョン

- 2.9.1
- 2.8.6
- 2.7.4
- 2.6.10
- 2.5.3
- 2.4.1
- 2.3.2
- 2.2.18
- 2.1.13
- 2.0.10
- 1.7.35
- 1.6.5
- 1.5.2
- 1.4.28

### 更新手順

#### CocoaPodsをご利用の場合

##### 現在ご利用中のSDKバージョンを確認する

アプリのプロジェクト配下にある `Podfile.lock` に現在ご利用中のSDKバージョンが記載されています。以下の例では `2.8.5` がご利用中のバージョンとなるため、バックポート版の `2.8.6` に更新してください。

例: Podfile.lock

```
PODS:
- Repro (2.8.5)
```

##### バックポート版に更新する

アプリのプロジェクト配下にある `Podfile` にてバックポート版のSDKバージョンを指定してください。以下の例ではバックポート版の `2.8.6` を指定しています。

例: Podfile

```ruby
target 'YOUR-PROJECT-NAME' do
    pod 'Repro', '2.8.6'
end
```

`Podfile` 変更後、以下のコマンドを実行してSDKをインストールしてください。

```sh
$ pod install
```

#### SDKをダウンロードして利用されている場合

##### 現在ご利用中のSDKバージョンを確認する

Xcodeでアプリのプロジェクトを開き、**Repro.embeddedframework > Resources > ReproSDKResources.bundle > Info.plist** を選択してください。右ペインに表示される **Bundle version** が現在ご利用中のSDKバージョンとなります。以下の例では `2.7.0` がご利用中のSDKバージョンとなるため、バックポート版の `2.7.4` に更新してください。



##### 現在ご利用中のSDKを削除する

プロジェクトから `Repro.xcframework` への参照を削除してください。



##### バックポート版のSDKをインストールする

[バックポート版のSDK](//github.com/reproio/repro-ios-sdk/releases) をダウンロードし、 `Repro.embeddedframework` ディレクトリをプロジェクトに追加してください（Xcodeへファイルを追加する際のオプションとして "Added folders: Create groups" を選択することをお勧めします）。



### 更新時の注意事項

- WebViewでイベントトラッキングをご利用の場合に、iOS SDK `1.7.0~1.7.24` からバックポート版の `1.7.35` に更新する際は、HTMLから読み込むRepro JavaScriptライブラリのURLを変更してください。URL中のドメイン名およびファイルパスが変更となります。
  - ドメイン名: `cdn.repro.io` -> `cdn.reproio.com`
  - ファイルパス: `/js/v1/dummy.repro.js` -> `/js/v2/repro.js`

```diff
<head>
...
-   <script src="//cdn.repro.io/js/v1/dummy.repro.js" type="text/javascript" charset="utf-8"></script>
+   <script src="//cdn.reproio.com/js/v2/repro.js" type="text/javascript" charset="utf-8"></script>
...
</head>
```

- アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。

---

## バックポート版への更新手順: Android

2018年2月20日時点でサポートしているSDKのすべてのマイナーバージョンごとに、起動時の通信先のURLのみを変更したバックポート版をリリースしました。ご利用中のSDKバージョンのマイナーバージョン(バージョン番号の2桁目)を確認し、最も近いバージョンへ更新してください。

### バックポート版のAndroid SDKバージョン

- 2.10.1
- 2.9.10
- 2.8.3
- 2.7.11
- 2.6.12
- 2.5.14
- 2.4.1
- 2.3.17
- 2.2.1
- 2.1.23
- 2.0.5
- 1.2.10
- 1.1.48
- 1.0.2
- 0.15.1
- 0.14.6
- 0.13.23

### 更新手順

#### Android Studioをご利用の場合

##### 現在ご利用中のSDKバージョンを確認する

アプリの `app/build.gradle` に現在ご利用中のSDKバージョンが記載されています。以下の例では `2.9.0` がご利用中のバージョンとなるため、バックポート版の `2.9.10` に更新してください。

```groovy
dependencies {
    ...
    compile 'io.repro:repro-android-sdk:2.9.0'
    ...
}
```

##### バックポート版に更新する

アプリの `app/build.gradle` にてバックポート版のSDKバージョンを指定してください。以下の例ではバックポート版の `2.9.10` を指定しています。

```groovy
dependencies {
    ...
    compile 'io.repro:repro-android-sdk:2.9.10'
    ...
}
```

#### Eclipseをご利用の場合

##### 現在ご利用中のSDKバージョンを確認する

ワークスペースの **repro > libs** に含まれるjarファイルの名前が現在ご利用中のSDKバージョンとなります。以下の例では `2.9.0` がご利用中のバージョンとなるため、バックポート版の `2.9.10` に更新してください。



##### 現在ご利用中のSDKを削除する

ワークスペースから **repro** プロジェクトを削除してください



##### バックポート版をImportする

- バックポート版のEclipse用SDKをダウンロードして解凍してください
  - Eclipse用SDKは `https://cdn.reproio.com/android/libprj/repro-android-sdk-libprj-x.x.x.zip` からダウンロード可能です。例えば `2.9.10` をダウンロードする場合は `https://cdn.reproio.com/android/libprj/repro-android-sdk-libprj-2.9.10.zip` となります。
- **File > Import...** を選択します


- **Android > Existing Android Code into Workspace** を選択し、 **Next** をクリックします


- 解凍したディレクトリを **Root Directory** に指定し、**Copy projects into workspace** にチェックを入れて **Finish** をクリックします



### 更新時の注意事項

- Eclipseをご利用の場合に、Android SDK `1.1.2~1.1.28` からバックポート版の `1.1.48` に更新する際は、アプリの `AndroidManifest.xml` に以下のBroadcastReceiverを登録してください。なお、Reproのプッシュ通知機能をご利用にならない場合はBroadcastReceiver登録は不要です。

```diff
+    <receiver
+        android:name="io.repro.android.notification.IntentHandler"
+        android:exported="false">
+        <intent-filter>
+            <action android:name="io.repro.android.notification.IntentHandler.START_ACTIVITY" />
+        </intent-filter>
+    </receiver>
```

- Eclipseをご利用の場合に、Android SDK `1.1.2~1.1.29` からバックポート版の `1.1.48` に更新する際は、アプリの `AndroidManifest.xml` から以下のActivityを削除してください。

```diff
-   <activity
-       android:name="io.repro.android.message.MessageActivity"
-       android:theme="@style/io_repro_android_MessageActivityTheme"/>
```

- WebViewでイベントトラッキングをご利用の場合に、Android SDK `1.1.2~1.1.37` からバックポート版の `1.1.48` に更新する際は、HTMLから読み込むRepro JavaScriptライブラリのURLを変更してください。URL中のドメイン名およびファイルパスが変更となります。
  - ドメイン名: `cdn.repro.io` -> `cdn.reproio.com`
  - ファイルパス: `/js/v1/dummy.repro.js` -> `/js/v2/repro.js`

```diff
<head>
...
-   <script src="//cdn.repro.io/js/v1/dummy.repro.js" type="text/javascript" charset="utf-8"></script>
+   <script src="//cdn.reproio.com/js/v2/repro.js" type="text/javascript" charset="utf-8"></script>
...
</head>
```

- アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。

---

## バックポート版への更新手順: Unity

2018年2月20日時点でサポートしているUnity Packageのすべてのマイナーバージョンごとに、起動時の通信先のURLのみを変更したバックポート版をリリースしました。ご利用中のUnity Packageバージョンのマイナーバージョン(バージョン番号の2桁目)を確認し、最も近いバージョンへ更新してください。

### バックポート版のUnity Packageバージョン

- 3.5.1
- 3.1.3
- 3.0.3
- 2.1.3
- 2.0.3

### 更新手順

#### 現在ご利用中のUnity Packageバージョンを確認する

Unityプロジェクトの **Plugins > Repro > VERSION** ファイルに現在ご利用中のバージョンが記載されています。以下の例では `3.5.0` がご利用中のバージョンとなるため、バックポート版の `3.5.1` に更新してください。

例: VERSION

```
3.5.0
```

#### 現在ご利用中のUnity Packageを削除する

Unityプロジェクトに含まれる以下のディレクトリとファイルを削除してください。

##### Unity5以上

- `Assets/Editor/Repro`
- `Assets/Plugins/Repro`
- `Assets/Plugins/iOS/Repro`
- `Assets/Plugins/Android/Repro`
- `Assets/Plugins/Android/libs/repro-android-sdk-x.x.x.aar`

##### Unity4

- `Assets/Editor/Repro`
- `Assets/Plugins/Repro`
- `Assets/Plugins/iOS/Repro`
- `Assets/Plugins/Android/Repro`

#### バックポート版をImportする

[こちら](//github.com/reproio/repro-unity-sdk/releases) からバックポート版のUnity Packageをダウンロードして、UnityプロジェクトにImportしてください。

##### Unity5以上

- **Assets > Import Package > Custom Package...** を選択します
- `Repro-unity5.unitypackage` をImportします

##### Unity4

- **Assets > Import Package > Custom Package...** を選択します
- `Repro-unity4.unitypackage` をImportします

### 更新時の注意事項

アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。

---

## バックポート版への更新手順: Cordova

2018年2月20日時点でサポートしているPluginのすべてのマイナーバージョンごとに、起動時の通信先のURLのみを変更したバックポート版をリリースしました。ご利用中のPluginバージョンのマイナーバージョン(バージョン番号の2桁目)を確認し、最も近いバージョンへ更新してください。

### バックポート版のCordova Pluginバージョン

- 3.6.2
- 3.1.3
- 3.0.3
- 2.3.2
- 2.2.1
- 2.0.2

### 更新手順

#### 現在ご利用中のPluginバージョンを確認する

`cordova plugin ls` コマンドを実行してください。以下の例では `3.6.1` がご利用中のバージョンとなるため、バックポート版の `3.6.2` に更新してください。

```sh
$ cordova plugin ls
cordova-plugin-repro 3.6.1 "Repro"
```

#### 現在ご利用中のPluginを削除する

以下のコマンドを実行して現在ご利用中のPluginを削除してください。

```sh
$ cordova plugin rm cordova-plugin-repro
```

#### バックポート版Pluginを追加する

バックポート版のバージョン番号を指定して `cordova plugin add` コマンドを実行してください。以下の例では `3.6.2` を指定しています。

```sh
$ cordova plugin add cordova-plugin-repro@3.6.2
```

### 更新時の注意事項

アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。

---

## バックポート版への更新手順: Cordova(Monaca)

2018年2月20日時点でサポートしているPluginのすべてのマイナーバージョンごとに、起動時の通信先のURLのみを変更したバックポート版をリリースしました。ご利用中のPluginバージョンのマイナーバージョン(バージョン番号の2桁目)を確認し、最も近いバージョンへ更新してください。

### バックポート版のCordova Pluginバージョン

- 3.6.2
- 3.1.3
- 3.0.3
- 2.3.2
- 2.2.1
- 2.0.2

### 更新手順

#### 現在ご利用中のPluginバージョンを確認する

**設定 > Cordovaプラグインの管理...** をクリックしてプラグインの一覧を表示し、**Repro** をクリックしてください。



**設定** をクリックしてください。



**プラグインバージョン** に現在ご利用中のバージョンが記載されています。以下の例では `3.6.1` がご利用中のバージョンとなるため、バックポート版の `3.6.2` への更新が必要となります。



#### バックポート版に更新する

**プラグインバージョン** でバックポート版を選択し **OK** をクリックしてください。以下の例ではバックポート版の `3.6.2` を選択しています。



##### NOTE
MonacaをFREEプランでご利用の場合は、アプリに導入済みのプラグインのバージョンを変更することができません。その場合 [こちら](#upgrade-to-latest-cordova-plugin) の手順に従って最新版のRepro Cordova Pluginをご利用ください。



### Monaca FREEプランで最新版のPluginを導入する手順

#### 現在ご利用中のPluginを無効にする

**設定 > Cordovaプラグインの管理...** をクリックしてプラグインの一覧を表示し、**Repro** をクリックしてください。



**無効** をクリックしてください。



一度プロジェクトを閉じてダッシュボードに戻ってください。

#### 最新版のPluginを有効にする

再度プロジェクトを開き、 **設定 > Cordovaプラグインの管理...** をクリックしてプラグインの一覧を表示し、**Repro** をクリックしてください。



**有効** をクリックしてください。



##### NOTE
最新版のPluginを導入するにあたり、[Cordova Plugin リリースノート](https://docs.repro.io/ja/releases/sdk/cordova/releases.md) をご確認の上、現在ご利用中のPluginと最新版Pluginの変更内容をご確認ください。

### 更新時の注意事項

アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。

---

## バックポート版への更新手順: Cocos2d-x

Cocos2d-x SDK 2.0.0に対し、起動時の通信先のURLのみを変更した2.0.1をリリースしました。以下の手順に従ってSDKを更新してください。

### 更新手順

#### Cocos2d-x SDK 2.0.0を削除する

Xcodeプロジェクトから `ReproCpp.h/ReproCpp.mm` および `Repro.framework` を削除してください。



Android Studio用プロジェクトから `repro-android-sdk-2.3.9.aar` を削除してください。



Android Studio用プロジェクトの `app/build.gradle` から以下を削除してください。

```diff
dependencies {
    ...
-    compile(name: 'repro-android-sdk-2.3.9', ext:'aar')
    ...
}
```

#### Cocos2d-x SDK 2.0.1を導入する

[導入: Cocos2d-x](https://docs.repro.io/ja/dev/sdk/getstarted/cocos2d-x.md) に従い2.0.1を導入してください。



### 更新時の注意事項

アプリにて通信先ドメインを制限している場合は `*.reproio.com` を許可してください。

---

## WebView用JavaScriptライブラリダウンロードURLの変更

WebView用JavaScriptライブラリをロードするURLのドメイン名を `cdn.repro.io` から `cdn.reproio.com` に変更してください。

**v1/dummy.repro.js をご利用の場合**

```diff
<head>
...
-   <script src="//cdn.repro.io/js/v1/dummy.repro.js" type="text/javascript" charset="utf-8"></script>
+   <script src="//cdn.reproio.com/js/v1/dummy.repro.js" type="text/javascript" charset="utf-8"></script>
...
</head>
```

**v2/repro.js をご利用の場合**

```diff
<head>
...
-   <script src="//cdn.repro.io/js/v2/repro.js" type="text/javascript" charset="utf-8"></script>
+   <script src="//cdn.reproio.com/js/v2/repro.js" type="text/javascript" charset="utf-8"></script>
...
</head>
```

**v3/repro.js をご利用の場合**

```diff
<head>
...
-   <script src="//cdn.repro.io/js/v3/repro.js" type="text/javascript" charset="utf-8"></script>
+   <script src="//cdn.reproio.com/js/v3/repro.js" type="text/javascript" charset="utf-8"></script>
...
</head>
```

---

## プッシュAPIエンドポイントの変更

プッシュAPIのエンドポイントを以下のように変更してください。

- 変更前: `https://marketing.repro.io/v1/push/<push_id>/deliver`
- 変更後: `https://marketing.reproio.com/v1/push/<push_id>/deliver`

##### NOTE
- 現在Web SDKではプッシュ通知をサポートしておりません。

---

## ユーザープロフィールAPIエンドポイントの変更

ユーザープロフィールAPIのエンドポイントを以下のように変更してください。

- 変更前: `https://api.repro.io/v2/user_profiles`
- 変更後: `https://api.reproio.com/v2/user_profiles`

---

## アプリ内パラメーター

### Remote Config インターフェース

アプリ内パラメーターの各機能は次のAPIより利用可能です。

```objc
[Repro remoteConfig]
```

```swift
Repro.remoteConfig
```

```java
Repro.getRemoteConfig()
```

```kotlin
Repro.getRemoteConfig()
```

```cpp
ReproCpp::getRemoteConfig()
```

```csharp
Repro.RemoteConfig
```

```js-cordova
Repro.remoteConfig
```

```js-react-native
Repro.remoteConfig
```

```dart
Repro.remoteConfig
```

#### ローカルのデフォルト値を設定する

2つの方法が利用できます。

##### Dictionary/Map/JSONを利用する

```objc
// setDefaultsFromDictionary must be executed before [Repro setup].
[[Repro remoteConfig] setDefaultsFromDictionary: @{ @"key1": @"value1", @"key2": @"value2" }];
```

```swift
// setDefaults must be executed before Repro.setup().
Repro.remoteConfig.setDefaults(fromDictionary: ["key1": "value1", "key2": "value2"]);
```

```java
// setDefaultsFromMap must be executed before Repro.setup().
HashMap<String, Object> values = new HashMap<>();
values.put("key1", "value1");
values.put("key2", "value2");
Repro.getRemoteConfig().setDefaultsFromMap(values);
```

```kotlin
// setDefaultsFromMap must be executed before Repro.setup().
val values: HashMap<String, Any> = HashMap()
values["key1"] = "value1"
values["key2"] = "value2"
Repro.getRemoteConfig().setDefaultsFromMap(values)
```

```cpp
// setDefaultsFromMap must be executed before ReproCpp::setup().
std::map<std::string, std::string> defaults;
defaults["key1"] = "value1";
defaults["key2"] = "value2";
ReproCpp::getRemoteConfig().setDefaultsFromMap(defaults);
```

```csharp
// SetDefaultsFromMap must be executed before Repro.Setup().
var dic = new Dictionary<string, object>();
dic.Add("key1", "value1");
dic.Add("key2", "value2");
Repro.RemoteConfig.SetDefaultsFromMap(dic);
```

```js-cordova
// setDefaultsFromJson must be executed before Repro.setup().
Repro.remoteConfig.setDefaultsFromJson(
    {"key1": "value1", "key2": "value2"},
    function(message) {
        // success callback
    },
    function(message) {
        // error callback
    }
);
```

```js-react-native
Repro.remoteConfig.setDefaultsFromDictionary({
    key1: "value1",
    key2: "value2",
});
```

```dart
Repro.remoteConfig.setDefaultsFromMap({
    'key1' : 'value1',
    'key2' : 'value2',
});
```

##### Json文字列を利用する

```objc
// setDefaultsFromJsonString must be executed before [Repro setup].
[[Repro remoteConfig] setDefaultsFromJsonString: @"{\"key1\": \"value1\", \"key2\": \"value2\"}"];
```

```swift
// setDefaults must be executed before Repro.setup().
Repro.remoteConfig.setDefaults(fromJsonString: "{\"key1\": \"value1\", \"key2\": \"value2\"}")
```

```java
// setDefaultsFromJsonString must be executed before Repro.setup().
Repro.getRemoteConfig().setDefaultsFromJsonString("{\"key1\": \"value1\", \"key2\": \"value2\"}");
```

```kotlin
// setDefaultsFromJsonString must be executed before Repro.setup().
Repro.getRemoteConfig().setDefaultsFromJsonString("{\"key1\": \"value1\", \"key2\": \"value2\"}")
```

```cpp
// setDefaultsFromJsonString must be executed before ReproCpp::setup().
ReproCpp::getRemoteConfig().setDefaultsFromJsonString("{\"key1\": \"value1\", \"key2\": \"value2\"}");
```

```csharp
// SetDefaultsFromJsonString must be executed before Repro.Setup().
Repro.RemoteConfig.SetDefaultsFromJsonString("{\"key1\": \"value1\", \"key2\": \"value2\"}");
```

```js-cordova
// setDefaultsFromJsonString must be executed before Repro.setup().
Repro.remoteConfig.setDefaultsFromJsonString(
    "{\"key1\": \"value1\", \"key2\": \"value2\"}",
    function(message) {
        // success callback
    },
    function(message) {
        // error callback
    }
);
```

```js-react-native
Repro.remoteConfig.setDefaultsFromJsonString("{\"key1\": \"value1\", \"key2\": \"value2\"}");
```

```dart
await Repro.remoteConfig.setDefaultsFromJsonString("{\"key1\": \"value1\", \"key2\": \"value2\"}");
```

### Remote Config の値にアクセスする

#### 特定の値にアクセスする

特定の値を取得する場合はキーを完全一致で指定します。

```objc
// The return value of [[Repro remoteConfig] valueForKey: "key1"] is always an RPRRemoteConfigValue instance and will never be nil.
NSString *string = [[Repro remoteConfig] valueForKey: @"key1"].stringValue;
```

```swift
// The return value of Repro.remoteConfig.value(forKey: 'key1') is always an RPRRemoteConfigValue instance and will never be nil.
if let value: String = Repro.remoteConfig.value(forKey: "key1").stringValue {
    // ... use value ...
    // stringValue will be nil if 'key1' is not found in
    // either the remote config or the local fallback
}
```

```java
// The return value of Repro.getRemoteConfig().get('key1') is always an RPRRemoteConfigValue instance and will never be nil.
// If no value exists for a given key, the RemoteConfigValue's asString() returns null, but toString() returns an empty string.
String value = Repro.getRemoteConfig().get("key1").asString();
```

```kotlin
// The return value of Repro.getRemoteConfig().get('key1') is always an RPRRemoteConfigValue instance and will never be nil.
// If no value exists for a given key, the RemoteConfigValue's asString() returns null, but toString() returns an empty string.
val value = Repro.getRemoteConfig().get("key1").asString()
```

```cpp
// The return value of ReproCpp::getRemoteConfig().get("key1") is always an RPRRemoteConfigValue instance and will never be nil.
const char* value = ReproCpp::getRemoteConfig().get("key1").getStringValue();
```

```csharp
// The return value of Repro.RemoteConfig.Get("key1") is always an RPRRemoteConfigValue instance and will never be nil.
string value = Repro.RemoteConfig.Get("key1").AsString();
```

```js-cordova
// If no value exists for the given key, the value returned by the success callback will be null.
Repro.remoteConfig.getValue(
    "key1",
    function(value) {
        const stringValue = value;
        // success callback
    },
    function(message) {
        // error callback
    }
);
```

```js-react-native
// If no value exists for the given key, the value returned by the callback will be null.
Repro.remoteConfig.getValue("key1", (value) => {
    let string = value.toString();
});
```

```dart
// The return value of Repro.remoteConfig.get('key1') is always an RPRRemoteConfigValue instance and will never be nil.
var remoteConfigValue = await Repro.remoteConfig.get('key1');
var stringValue = remoteConfigValue.asString();
```

#### Remote Config全体

全ての値を取得する場合は `allValues` を使用します。

```objc
// Returns a Dictionary with all values.
NSDictionary<NSString *, RPRRemoteConfigValue *> *values = [[Repro remoteConfig] allValues]
```

```swift
// Returns a Dictionary with all values.
var values: Dictionary<NSString, RPRRemoteConfigValue> = Repro.remoteConfig.allValues()
```

```java
// Returns a Map with all values.
Map<String, RemoteConfigValue> values = Repro.getRemoteConfig().getAllValues();
```

```kotlin
// Returns a Map with all values.
Map<String, RemoteConfigValue> values = Repro.getRemoteConfig().getAllValues()
```

```cpp
// Returns a Map with all values.
std::map<std::string, RemoteConfigValue*> values = ReproCpp::getRemoteConfig().getAllValues();
```

```csharp
// Returns a Dictionary with all values.
Dictionary<string, RemoteConfigValue> value = Repro.RemoteConfig.GetAllValues();
```

```js-cordova
// Returns an associative array with all values.
Repro.remoteConfig.getAllValues(
    function(values) {
        // success callback
    }
);
```

```js-react-native
// Returns an associative array with all values.
Repro.remoteConfig.getAllValues((values) => {
    console.log(values);
});
```

```dart
// Returns a Map with all values.
var values = await Repro.remoteConfig.getAllValues();
```

#### プリフィックスを指定してアクセスする

特定のキーワードに先頭がマッチするキーの値すべてを取得する場合はプリフィックスを指定します。

```objc
// Returns a Dictionary with key values ​​starting with "color".
NSDictionary<NSString *, RPRRemoteConfigValue *> *values = [[Repro remoteConfig] allValuesWithPrefix: @"color"]
```

```swift
// Returns a Dictionary with key values ​​starting with "color".
var values: Dictionary<NSString, RPRRemoteConfigValue> = Repro.remoteConfig.allValues(withPrefix: "color")
```

```java
// Returns a Map with key values ​​starting with "color".
Map<String, RemoteConfigValue> values = Repro.getRemoteConfig().getAllValuesWithPrefix("color");
```

```kotlin
// Returns a Map with key values ​​starting with "color".
Map<String, RemoteConfigValue> values = Repro.getRemoteConfig().getAllValuesWithPrefix("color")
```

```cpp
// Returns a Map with key values ​​starting with "color".
std::map<std::string, RemoteConfigValue*> = ReproCpp::getRemoteConfig().getAllValuesWithPrefix("color");
```

```csharp
// Returns a Dictionary with key values ​​starting with "color".
Dictionary<string, RemoteConfigValue> value = Repro.RemoteConfig.GetAllValuesWithPrefix("color");
```

```js-cordova
// Returns an associative array with key values ​​starting with "color".
Repro.remoteConfig.getAllValuesWithPrefix("color",
    function(values) {
        // success callback
    }
);
```

```js-react-native
// Returns an associative array with key values ​​starting with "color".
Repro.remoteConfig.getAllValuesWithPrefix("color", (values) => {
    console.log(values);
});
```

```dart
// Returns a Map with key values ​​starting with "color".
var values = await Repro.remoteConfig.getAllValuesWithPrefix("color");
```

#### 値をリセットする

Remote Configオブジェクトを初期状態に戻したい場合は `forceReset()` を呼び出してください。 `forceReset()` の実行後は、ローカルのデフォルト値やコールバックを再びセットする必要があります。

```objc
[[Repro remoteConfig] forceReset]
```

```swift
Repro.remoteConfig.forceReset()
```

```java
Repro.getRemoteConfig().forceReset()
```

```kotlin
Repro.getRemoteConfig().forceReset()
```

```cpp
ReproCpp::getRemoteConfig().forceReset()
```

```csharp
Repro.RemoteConfig.ForceReset()
```

```js-cordova
Repro.remoteConfig.forceReset()
```

```js-react-native
Repro.remoteConfig.forceReset()
```

```dart
await Repro.remoteConfig.forceReset()
```

#### Fetch と Activate

Remote Configの値はアプリがフォアグラウンドに遷移するたびに自動的にReproのサーバーから取得し直されるため、fetchコールバックは必ず必要というわけではありません。取得した設定値を反映する場合は `activateFetched()` を呼び出してください。
古いRemote Configの値を新しく取得された値で置き換えるタイミングを制御したい場合はfetchコールバックを利用することを推奨します。

- 登録できるコールバックは1つです。
- コールバックは必ず実行されることを保証するものではありません。
- コールバックの中でUI上の要素を更新することも可能です。
- `fetch()` を実行しても、タイムアウトまたは `Repro.setup()` が呼び出されるまで実際の処理およびコールバックが実行されることはありません。
- `activateFetched()` はコールバックの実行完了後に呼び出してください。コールバックのブロックの中から呼び出すことも可能です。

fetch の例

```objc
// The timeout is specified in seconds using NSTimeInterval.
[[Repro remoteConfig] fetchWithTimeout:3.0 completionHandler:^(RPRRemoteConfigFetchStatus fetchStatus) {
    if (fetchStatus == RPRRemoteConfigFetchStatusSuccess) {
        NSDictionary<NSString *, RPRRemoteConfigValue *> *oldValues = [[Repro remoteConfig] allValues];
        for (id key in [oldValues keyEnumerator]) {
            NSLog(@"OLD Remote Config Key:%@ Value:%@", key, [oldValues valueForKey:key]);
        }

        [[Repro remoteConfig] activateFetched];

        NSDictionary<NSString *, RPRRemoteConfigValue *> *newValues = [[Repro remoteConfig] allValues];
        for (id key in [newValues keyEnumerator]) {
            NSLog(@"OLD Remote Config Key:%@ Value:%@", key, [newValues valueForKey:key]);
        }
    }
}];
```

```swift
// The timeout is specified in seconds using NSTimeInterval.
Repro.remoteConfig.fetch(withTimeout: 3.0) { status in
    if status == .success {
        print("OLD Remote Config Values: \(Repro.remoteConfig.allValues())")
        Repro.remoteConfig.activateFetched()
        print("NEW Remote Config Values: \(Repro.remoteConfig.allValues())")
    }
}
```

```java
// The timeout is specified in milliseconds.
Repro.getRemoteConfig().fetch(3000, new RemoteConfigListener() {
    @Override
    public void onCompletion(FetchStatus status) {
        if (status == FetchStatus.SUCCESS) {
            Log.d("remote_config", "BEFORE " + Repro.getRemoteConfig().getAllValues().toString());
            Repro.getRemoteConfig().activateFetched();
            Log.d("remote_config", "AFTER  " + Repro.getRemoteConfig().getAllValues().toString());
        }
    }
});
```

```kotlin
// The timeout is specified in milliseconds.
Repro.getRemoteConfig().fetch(3000) { status ->
    if (status == FetchStatus.SUCCESS) {
        Log.d("remote_config", "BEFORE " + Repro.getRemoteConfig().allValues.toString())
        Repro.getRemoteConfig().activateFetched()
        Log.d("remote_config", "AFTER  " + Repro.getRemoteConfig().allValues.toString())
    }
}
```

```cpp
// The timeout is specified in seconds.
ReproCpp::getRemoteConfig().fetch(3, [](ReproCpp::RemoteConfig::FetchStatus status) {
    if (status == ReproCpp::RemoteConfig::FetchStatusSuccess) {
        log("fetch result: FetchStatusSuccess");
        ReproCpp::getRemoteConfig().activateFetched();
    }
});
```

```csharp
// The timeout is specified in milliseconds.
Repro.RemoteConfig.Fetch(3000, (status) =>
{
    if (status == Repro.FetchStatus.Success)
    {
        var str = string.Join(", ", Repro.RemoteConfig.GetAllValues().Select(elem => elem.Key + " => " + elem.Value.ToString()).ToArray());
        Debug.Log("RemoteConfig Values(Before ActivateFetched): " + str);

        Repro.RemoteConfig.ActivateFetched();

        str = string.Join(", ", Repro.RemoteConfig.GetAllValues().Select(elem => elem.Key + " => " + elem.Value.ToString()).ToArray());
        Debug.Log("RemoteConfig Values(After ActivateFetched): " + str);
    }
});
```

```js-cordova
// The timeout is specified in milliseconds.
Repro.remoteConfig.fetch(3000, function(status) {
    // success callback
    if (status == Repro.remoteConfig.FetchStatus.Success) {
        Repro.remoteConfig.getAllValues((values) => {
            console.log(values);
            Repro.remoteConfig.activateFetched(function(message) {
                // success callback
                Repro.remoteConfig.getAllValues((values) => {
                    console.log(values);
                });
            }, function(message) {
                // error callback
            });
        });
    } else if (status == Repro.remoteConfig.FetchStatus.AlreadyFetched) {
    }
}, function(status) {
    // error callback
});
```

```js-react-native
// The timeout is specified in milliseconds.
Repro.remoteConfig.fetch(3000, (status) => {
    if (status == Repro.remoteConfig.FETCH_STATUS.REMOTE_CONFIG_SUCCESS) {
        Repro.remoteConfig.getAllValues((values) => {
            console.log(values);
            Repro.remoteConfig.activateFetched();
            Repro.remoteConfig.getAllValues((values) => {
                console.log(values);
            });
        });
    } else if (status == Repro.remoteConfig.FETCH_STATUS.REMOTE_CONFIG_TIMEOUT_REACHED) {
    } else if (status == Repro.remoteConfig.FETCH_STATUS.REMOTE_CONFIG_ALREADY_FETCHED) {
    }
});
```

```dart
// The timeout is specified in milliseconds.
await Repro.remoteConfig.fetch(3000, (result) {
    if (result == FetchStatus.success) {
        var values = await Repro.remoteConfig.getAllValues();
        for (var key in values.keys) {
            debugPrint('[old RemoteConfig] $key: ${values[key]}');
        }
        await Repro.remoteConfig.activateFetched();
        values = await Repro.remoteConfig.getAllValues();
        for (var key in values.keys) {
            debugPrint('[new RemoteConfig] $key: ${values[key]}');
        }
    }
});
```

---

## FCMへの移行手順: Cordova

Googleからアナウンスされている通り、GCMは2019/4/11までに廃止が予定されております。すでにReproのプッシュ通知をGCMで実装している場合は、それまでに以下の手順を参照し、FCMでの実装に移行してください。

### 移行手順

#### Google Cloud PlatformのプロジェクトをFirebase Consoleへ移行する

Firebase ConsoleからGCMで利用していたプロジェクトを選択して作成してください：


* Google Cloud Platformのプロジェクト番号と、Firebase Consoleの送信者IDが同一であるか確認してください。Google Cloud Platformのプロジェクト番号は **Google Cloud Platform > IAMと管理 > 設定** のプロジェクト番号から確認できます：
  
* Firebase Consoleの送信者IDは **設定 > クラウドメッセージング** の送信者IDから確認できます：
  

#### FCMを設定する

1. [アプリの登録](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md#firebase-register-app) の手順を参照し、 `google-services.json` をダウンロードしてください。
2. [Firebaseの秘密鍵を生成](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md#firebase-generate-private-key) と [Firebaseの秘密鍵をReproに登録](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md#firebase-register-private-key) の手順を参照し、Firebaseの秘密鍵をReproに登録してください。
3. [google-services.jsonファイルを追加する](https://docs.repro.io/ja/dev/sdk/push-notification/cordova.md#cordova-add-google-services-json) の手順を参照し、 `google-services.json` をプロジェクトに追加してください。

#### Repro Cordova Pluginのアップデート

下記のコマンドを実行してください。

```shell
$ cordova plugin rm cordova-plugin-repro
$ cordova plugin add cordova-plugin-repro
```

#### config.xmlファイルを編集する

`io.repro.android.GCMReceiver` を `io.repro.ReproReceiver` に修正してください：

```diff
 <receiver
-    android:name="io.repro.android.GCMReceiver"
+    android:name="io.repro.android.ReproReceiver"
     android:exported="true"
     android:permission="com.google.android.c2dm.permission.SEND">
     <intent-filter>
         <action android:name="com.google.android.c2dm.intent.RECEIVE" />
         <category android:name="YOUR_PACKAGE_NAME" />
     </intent-filter>
 </receiver>
```

#### Registration IDの取得方法を変更する

`Repro.enablePushNotification` もしくは `Repro.enablePushNotificationForAndroid` の呼び出しの引数を削除してください。

```diff
 var app = {
     ...
     onDeviceReady: function() {
         ...
-        Repro.enablePushNotification(SENDER_ID);
-        Repro.enablePushNotificationForAndroid(SENDER_ID);
+        Repro.enablePushNotificationForAndroid();
```

---

js-cordova

## プッシュ通知 (Monaca)

以下の手順は、MonacaクラウドIDEからiOSアプリをビルドできるよう設定済みであることを前提としています。MonacaクラウドIDEからiOSアプリをビルドする設定は [こちら](https://docs.monaca.io/ja/monaca_ide/manual/build/ios/build_ios/) をご覧ください。

### プッシュ通知の設定

[APNs証明書の設定 (iOS)](https://docs.repro.io/ja/dev/sdk/push-notification/setup-ios.md) と [FCMの設定 (Android)](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md) を参照し、設定してください。

#### Provisioning ProfileをMonacaクラウドIDEに登録する

Monacaで **設定 > iOSビルド設定... > ビルド設定の管理** を開き、 **プロファイルのアップロード** をクリックし、[APNs証明書の設定 (iOS)](https://docs.repro.io/ja/dev/sdk/push-notification/setup-ios.md) でダウンロードしたProvisioning Profileを選択してください。





### `config.xml` ファイルを編集する

##### NOTE
* Cordova 7.1未満をご利用の場合は設定方法が異なります。詳細は [Cordova 7.1未満を利用する場合の設定](https://docs.repro.io/ja/dev/sdk/push-notification/monaca-old-cordova.md#monaca-old-cli) を参照してください。

#### 名前空間および `platform` タグを追加する

プロジェクト直下のconfig.xmlを開き、 `widget` タグに `xmlns:android="http://schemas.android.com/apk/res/android"` を追加してください。また、config.xmlの中に `<platform name="android">` タグが存在しない場合、 `widget` タグの下に追加してください。

```xml
<widget xmlns="http://www.w3.org/ns/widgets"
        xmlns:android="http://schemas.android.com/apk/res/android"
        id="..." version="1.0.0">
    ...
    <platform name="android">
        ...
    </platform>
```

#### config-fileタグを追加する

以下の手順で `config-file` タグを追加してください。

##### Receiverの登録

以下のXML中の "YOUR_PACKAGE_NAME" をアプリケーションのパッケージ名に置き換え、config.xmlの `<platform name="android">` タグの中に追加してください。

```xml
<config-file target="AndroidManifest.xml" parent="./application">
    <receiver
        android:name="io.repro.android.ReproReceiver"
        android:exported="true"
        android:permission="com.google.android.c2dm.permission.SEND">
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <category android:name="YOUR_PACKAGE_NAME" />
        </intent-filter>
    </receiver>
</config-file>
```

##### アイコンと背景色のカスタマイズ

Android5.0以降の機種で、通知エリアに表示されるアイコンとその背景色をカスタマイズする場合は、以下のXMLをconfig.xmlの `<platform name="android">` タグの中に追加してください。Android5.0未満の機種では以下の設定は無視され、通知エリアにはアプリケーションのアイコンおよびシステムデフォルトの背景色が使用されます。

```xml
<config-file target="AndroidManifest.xml" parent="./application">
    <meta-data
        android:name="io.repro.android.PushNotification.SmallIcon"
        android:resource="@drawable/YOUR_ICON_ID">
    </meta-data>

    <meta-data
        android:name="io.repro.android.PushNotification.AccentColor"
        android:resource="@color/YOUR_COLOR_ID">
    </meta-data>
</config-file>
```

##### 通知チャンネルの設定

Android Oにて、ユーザーが通知を管理できるように通知チャンネルが導入されました。

Repro SDKで利用する通知チャンネルの設定を行うには、「ID」「名前」「ユーザー向けの説明」「badgeの表示有無」を以下のようにconfig.xmlの `<platform name="android">` タグの中に追加してください。IDと名前の指定は必須、その他は省略可能です。「ユーザー向けの説明」省略時は空文字列、「badgeの表示有無」省略時はbadgeの表示有りとなります。

##### WARNING
- アプリのtargetSDKVersionが26以上かつAndroid O以降の機種で動作させる場合、IDと名前が指定されていなければSDKはReproからのプッシュ通知を表示いたしませんのでご注意ください。

```xml
<config-file target="AndroidManifest.xml" parent="./application">
    <meta-data
        android:name="io.repro.android.PushNotification.ChannelId"
        android:value="YOUR_CHANNEL_ID">
    </meta-data>

    <meta-data
        android:name="io.repro.android.PushNotification.ChannelName"
        android:resource="@string/channel_name">
    </meta-data>

    <meta-data
        android:name="io.repro.android.PushNotification.ChannelDescription"
        android:resource="@string/channel_description">
    </meta-data>

    <meta-data
        android:name="io.repro.android.PushNotification.ShowBadge"
        android:value="true">
    </meta-data>
</config-file>
```

指定されたIDの通知チャンネルが存在しない場合は上記の指定を基にSDKが自動で作成し、指定されたIDの通知チャンネルが存在する場合は既存のものを利用します。

既存のものを利用する場合、SDKは「名前」、「ユーザー向けの説明」及び「チャンネルの重要度」を更新します。

また、アプリのtargetSDKVersionが25以下の場合、あるいは、Android O未満の機種の場合は、SDKは上記の通知チャンネルに関する設定を無視します。

##### NOTE
通知チャンネルはAndroid Oで導入されたAndroidの標準機能です。通知チャンネルの詳細は [こちら](https://developer.android.com/preview/features/notification-channels.html?hl=ja) をご覧ください。

##### 文字列リソースの追加

通知チャンネルの設定に合わせて、 `channel_name` と `channel_description` の文字列リソースを追加します。以下のようにconfig.xmlの `<platform name="android">` タグの中に追加してください。

```xml
<config-file target="res/values/strings.xml" parent="/*">
    <string name="channel_name">YOUR_CHANNEL_NAME</string>
    <string name="channel_description">YOUR_CHANNEL_DESCRIPTION</string>
</config-file>
```



### `google-services.json` ファイルを追加する

[FCMの設定 (Android)](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md) でダウンロードした `google-services.json` をプロジェクトのディレクトリにアップロードします。



下記のXMLをconfig.xmlの `<platform name="android">` タグの中に追加してください。

```xml
<resource-file src="google-services.json" target="app/google-services.json" />
```

##### NOTE
* Cordova Android 7.0未満をご利用の場合は設定方法が異なります。詳細は [Cordova Android 7.0未満を利用する場合の設定](https://docs.repro.io/ja/dev/sdk/push-notification/monaca-old-cordova.md#monaca-old-android) を参照してください。

### Google Services Gradle Pluginを導入する

Google Services Gradle Pluginを導入します。

`config.xml` 内の `<platform name="android">` タグの中に、以下の記述を追加してください。

```xml
<preference name="GradlePluginGoogleServicesEnabled" value="true" />
<preference name="GradlePluginGoogleServicesVersion" value="4.3.15" />
```

##### NOTE
* Cordova Plugin 6.8.0未満の場合はReproによって自動的にGoogle Services Gradle Plugin導入されるため、この設定は不要です。

##### WARNING
* この手順によるGoogle Services Gradle Pluginの導入はCordova Android 9.0.0以降の場合のみ可能です。
* Cordova Plugin 6.8.0以上を利用している かつ Cordova Android 9.0.0未満を利用している場合は、別途Google Services Gradle Pluginの導入を行うか もしくはCordova Android 9.0.0以降へのアップデートを検討してください。

### オプション：Firebaseの依存バージョンを変更する

`firebase-core` 及び `firebase-messaging` の依存バージョンを変更する場合は、下記の手順で指定してください。

**設定 > Cordovaプラグインの管理** をクリックします。



**Repro** にカーソルを合わせ、 **設定** をクリックします。



インストールパラメータに `firebase-core` 及び `firebase-messaging` の依存バージョンを指定します。例えば、 `firebase-core` のバージョン16.0.0、 `firebase-messaging` のバージョン17.1.0を指定する場合は、下記のインストールパラメータを指定してください。

```text
FIREBASE_CORE_VERSION=16.0.0
FIREBASE_MESSAGING_VERSION=17.1.0
```

**OK** をクリックします。



### デバイストークン、Registration IDをReproに送信

プッシュ通知を利用するために、デバイストークン、Registration IDをReproに送信します。

index.htmlにてプッシュ通知の設定を行います。

```js-cordova
function onDeviceReady() {
  ...

  if (typeof Repro != "undefined") {
    // Setup Repro
    Repro.setup("YOUR_APP_TOKEN");

    // For iOS
    Repro.enablePushNotificationForIOS();

    // For Android
    Repro.enablePushNotificationForAndroid();
  }

  ...
}
```

上記の実装が終わったら、 [プッシュ通知作成画面](https://docs.repro.io/ja/dashboard/campaign/push-notification.md#push-create-message) をご覧ください。

#### プッシュ通知受信時の動作をカスタマイズする

Monacaでは [オプション：プッシュ通知受信時の動作をカスタマイズする](android.html#customize-receiver) に示すプッシュ通知受信時の動作のカスタマイズに対応しておりません。ご了承ください。

### オプション：ユニバーサルリンク/アプリリンクを使用する



端末に表示されたプッシュ通知およびアプリ内メッセージに設定されたリンクをタップした際に実行されるURLには、ユニバーサルリンク（またはアプリリンクと呼ばれる）を指定することが可能です。
（簡単のため、以下ではこれらをユニバーサルリンクと呼びます）

アプリにてユニバーサルリンクの実行時の処理を追加するには、以下の通り実装を行う必要があります。
（ここで設定された動作は、プッシュ通知およびアプリ内メッセージ対し有効となります。）

#### ユニバーサルリンクのURLパターンを登録する

ユニバーサルリンクを利用するためには、まずユニバーサルリンクのURLのパターン（正規表現）を指定する必要があります。

##### NOTE
パターン（正規表現）に合致すると、プッシュ通知の開封時や、アプリ内メッセージの遷移先に設定されたURLに対して、後述のコールバック処理をキックします。

また、アプリ内メッセージでHTMLコンテンツを表示するとき、そのコンテンツ内で発生したリクエストに対してもユニバーサルリンクの判定が行われます。

この指定は、iOSの場合は `AppDelegate` または `.plist` ファイル、Androidの場合は `Application` 継承クラス または `AndroidManifest.xml` ファイルのどちらか一方に記述することで行うことができます。

```objc
// AppDelegate.m

#import <Repro/Repro.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [Repro addOpenUrlFilterRegEx:@"https://example\\.com/page/"];
    [Repro addOpenUrlFilterRegEx:@"your-domain\\.com/.+\?universal=true"];
    ...
}


// .plist file
/*
<dict>
    <key>RPROpenUrlFilterRegExList</key>
    <array>
        <string>https://example\.com/page/</string>
        <string>your-domain\.com/.+\?universal=true</string>
    </array>
    ...
</dict>
*/
```

```java
// MyApplication.java

import io.repro.android.Repro;

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        Repro.addOpenUrlFilterRegEx("https://example\\.com/page/");
        Repro.addOpenUrlFilterRegEx("your-domain\\.com/.+\\?universal=true");
        ...
    }
...
}


// AndroidManifest.xml
// To specify multiple URL patterns, enter them separated by commas.
<application>
    ...
    <meta-data
        android:name="io.repro.android.OpenUrlFilterRegExList"
        android:value="https://example\\.com/page/;your-domain\\.com/.+\\?universal=true">
    </meta-data>
</application>
```

```kotlin
// MyApplication.kt

import io.repro.android.Repro

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        Repro.addOpenUrlFilterRegEx("https://example\\.com/page/")
        Repro.addOpenUrlFilterRegEx("your-domain\\.com/.+\\?universal=true")
        ...
    }
    ...
}


// AndroidManifest.xml
// To specify multiple URL patterns, enter them separated by commas.
<application>
    ...
    <meta-data
        android:name="io.repro.android.OpenUrlFilterRegExList"
        android:value="https://example\\.com/page/;your-domain\\.com/.+\\?universal=true">
    </meta-data>
</application>
```

```swift
// AppDelegate.swift

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
{
    Repro.add(openUrlFilterRegEx: "https://example\\.com/page/")
    Repro.add(openUrlFilterRegEx: "your-domain\\.com/.+\\?universal=true")
    ...
}

// .plist file
/*
<dict>
    <key>RPROpenUrlFilterRegExList</key>
    <array>
        <string>https://example\.com/page/</string>
        <string>your-domain\.com/.+\?universal=true</string>
    </array>
    ...
</dict>
*/
```

```dart
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

```csharp
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

```cpp
// YourAppNameScene.cpp

bool YourAppName::init() {
    ReproCpp::addOpenUrlFilterRegEx("https://example\\.com/page/");
    ReproCpp::addOpenUrlFilterRegEx("your-domain\\.com/.+\\?universal=true");
    ...
}
```

```js-cordova
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

```js-react-native
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

##### WARNING
ユニバーサルリンクとして設定するURLパターンは、可能な限り **ドメインとパスまで含めて具体的に指定** し、 **全て小文字で指定** してください。

もし、 https のようにスキームのみを指定した場合、アプリ内メッセージで表示された画面内で実行されたスクリプトなどによるリクエストもユニバーサルリンクと誤って判定され、意図しないタイミングでコールバック処理が実行される可能性があります。

また、URLパターンのスキーム/ドメイン部分に大文字を使用した場合、HTMLアプリ内メッセージで表示したボタンからユニバーサルリンクを使って遷移させようとするときに、スキーム/ドメイン部分が自動的に小文字に変換されて処理されます。パターン（正規表現）に一致せず、意図したタイミングでコールバック処理が実行されない可能性があります。

#### ユニバーサルリンク実行時の処理を登録する

次に、ユニバーサルリンクが実行された際に動作するコールバック処理を実装します。
処理内には、例えばURLのパターンに応じて画面遷移を行う動作などを記述します。

```objc
#import <Repro/Repro.h>

...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [Repro setOpenUrlCallback:^(NSURL *url) {
        if ([url.host isEqualToString:@"example.com"]) {
            // In case of your universal link perform navigation, present content, ...
            handleUniversalLink(url);
        }
    }];

    ...
    [Repro setup:@"YOUR_APP_TOKEN"];
    ...
}
```

```swift
// Set a callback that is executed everytime an URL is about to be opened
Repro.setOpenUrlCallback { url in
    if url.host == "example.com" {
        // In case of your universal link perform navigation, present content, ...
        handleUniversalLink(url)
    }
}
...
Repro.setup(token: "YOUR_APP_TOKEN")
...
```

```java
import io.repro.android.Repro;

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        // In order to execute a callback when a push notification is tapped,
        // the callback must be set in Application, not Activity.
        Repro.setOpenUrlCallback(new Repro.OpenUrlCallback() {
            // ** This callback method is executed in the main thread **
            @Override
            public void onOpened(Uri uri) {
                if ("example.com".equals(uri.getHost())) {
                    // In case of your universal link perform navigation, present content, ...
                }
            }
        });

        ...
        Repro.setup(this, YOUR_APP_TOKEN);
        ...
    }
    ...
}
```

```kotlin
import io.repro.android.Repro

class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        // In order to execute a callback when a push notification is tapped,
        // the callback must be set in Application, not Activity.
        Repro.setOpenUrlCallback { uri ->
            // ** This callback method is executed in the main thread **
            if (uri.host == "example.com") {
                // In case of your universal link perform navigation, present content, ...
            }
        }

        ...
        Repro.setup(this, "YOUR_APP_TOKEN")
        ...
    }
    ...
}
```

```dart
Repro.setOpenUrlCallback((uri) { // uri is of type Uri
   debugPrint("Universal Link Callback Handler received: " + uri.toString());
});
```

```csharp
// Somewhere before Repro.Setup(...)
Repro.SetOpenUrlCallback(uri => // uri is of type Uri
{
    Debug.Log("Universal Link Callback Handler received: " + uri.ToString());
});
```

```cpp
bool YourAppName::init() {
    ReproCpp::addOpenUrlFilterRegEx(...);

    ReproCpp::setOpenUrlCallback([](const char *url) {
        if (strcmp(url, "example.com") == 0) {
            // In case of your universal link perform navigation, present content, ...
        }
    });

    ReproCpp::setup("YOUR_APP_TOKEN")
    ...
}
```

```js-cordova
Repro.setOpenUrlCallback(function(url) { // url is of type String
    alert('Universal Link Callback Handler received: ' + url);
    if (url.includes("http://example.org")) {
        // In case of your universal link perform navigation, present content, ...
    }
});
```

```js-react-native
Repro.setOpenUrlCallback( (url) => {  // url is of type String
    console.log('Universal Link Callback Handler received: ' + url);
    if (url.includes("http://example.org")) {
        // In case of your universal link perform navigation, present content, ...
    }
});
```

---

## Monacaアプリにおける特定のバージョンのCordovaでの対応方法



### Cordova 7.1未満を利用する場合の設定

#### 名前空間および `platform` タグを追加する

プロジェクト直下のconfig.xmlを開き、 `widget` タグに `xmlns:android="http://schemas.android.com/apk/res/android"` を追加してください。また、config.xmlの中に `<platform name="android">` タグが存在しない場合、 `widget` タグの下に追加してください。

```xml
<widget xmlns="http://www.w3.org/ns/widgets"
        xmlns:android="http://schemas.android.com/apk/res/android"
        id="..." version="1.0.0">
    ...
    <platform name="android">
        ...
    </platform>
```

#### custom-config-fileタグを追加する

Cordova 7.1未満をご利用する場合、config-fileタグが動作しないため、以下の手順で `config.xml` を編集してください：

* cordova-custom-configを導入
  * [Monacaの公式ドキュメント](https://docs.monaca.io/ja/reference/third_party_phonegap/custom_config/) を参照し、cordova-custom-configを導入してください。
* [config-fileタグを追加する](monaca.html#config-file) にて設定したXMLを一つの `custom-config-file` タグの中に記述し、さらにその `custom-config-file` タグを `<platform name="android">` タグの中に追加してください
  * "YOUR_PACKAGE_NAME" をアプリケーションのパッケージ名に置き換えてください

  ```xml
  <custom-config-file parent="./application" target="AndroidManifest.xml">
      <!-- Receiver -->
      <receiver
          android:name="io.repro.android.ReproReceiver"
          android:exported="true"
          android:permission="com.google.android.c2dm.permission.SEND">
          <intent-filter>
              <action android:name="com.google.android.c2dm.intent.RECEIVE" />
              <category android:name="YOUR_PACKAGE_NAME" />
          </intent-filter>
      </receiver>

      <!-- Notification Channel -->
      <meta-data
          android:name="io.repro.android.PushNotification.ChannelId"
          android:value="YOUR_CHANNEL_ID">
      </meta-data>
      <meta-data
          android:name="io.repro.android.PushNotification.ChannelName"
          android:resource="@string/channel_name">
      </meta-data>
      <meta-data
          android:name="io.repro.android.PushNotification.ChannelDescription"
          android:resource="@string/channel_description">
      </meta-data>
      <meta-data
          android:name="io.repro.android.PushNotification.ShowBadge"
          android:value="true">
      </meta-data>

      <!-- Icon and Accent Color -->
      <meta-data
          android:name="io.repro.android.PushNotification.SmallIcon"
          android:resource="@drawable/YOUR_ICON_ID">
      </meta-data>

      <meta-data
          android:name="io.repro.android.PushNotification.AccentColor"
          android:resource="@color/YOUR_COLOR_ID">
      </meta-data>
  </custom-config-file>
  ```
* プロジェクト直下で下記の内容で `ReproStrings.xml` というファイルを作成してください：
  ```xml
  
  <resources>
      <string name="channel_name">YOUR_CHANNEL_NAME</string>
      <string name="channel_description">YOUR_CHANNEL_DESCRIPTION</string>
  </resources>
  ```
* config.xmlの `<platform name="android">` タグの中に下記の設定を追加してください：
  ```xml
  <resource-file src="ReproStrings.xml" target="res/values/ReproStrings.xml" />
  ```



### Cordova Android 7.0未満を利用する場合の設定

#### `google-services.json` ファイルを追加する

[FCMの設定 (Android)](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md) でダウンロードした `google-services.json` をプロジェクトのディレクトリにアップロードします。



下記のXMLをconfig.xmlの `<platform name="android">` タグの中に追加してください。

```xml
<resource-file src="google-services.json" target="google-services.json" />
```

---

objc,swift,js-react-native

## プッシュ通知 (React Native)

### プッシュ通知の設定 (iOS)

[APNs証明書の設定 (iOS)](https://docs.repro.io/ja/dev/sdk/push-notification/setup-ios.md) を参照し、設定してください。

#### デバイストークンをReproに送信

プッシュ通知の宛先を指定するためにデバイストークンをReproに送信します。

XcodeのCapabilitiesにてPush NotificationsをONにします。



デバイストークンの取得には、React Native コミュニティパッケージの [PushNotificationIOS](https://github.com/react-native-push-notification/ios) を利用することを推奨します。PushNotificationIOS のインストールに関しては、 [こちらのドキュメント](https://github.com/react-native-push-notification/ios?tab=readme-ov-file#getting-started) をご覧ください。

PushNotificationIOS を利用する場合のサンプルコードは以下の通りです。

```swift
// AppDelegate.swift
...
...
import Repro
import RNCPushNotificationIOS

@main
class AppDelegate: RCTAppDelegate, UNUserNotificationCenterDelegate {

    ...

    override func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        RNCPushNotificationIOS.didRegisterForRemoteNotifications(withDeviceToken: deviceToken)
    }

    ...

}
```

```js-react-native
// App.js etc...
import { Platform } from 'react-native';
import { PushNotificationIOS } from '@react-native-community/push-notification-ios';
import Repro from 'react-native-repro';

type Props = {};
export default class App extends Component<Props> {

    constructor(props) {
        super(props);

        if (Platform.OS === 'ios') {
            PushNotificationIOS.addEventListener("register", (deviceToken) => {
                console.log("iOS Push Notification Device Token: " + deviceToken);
                Repro.setPushToken(deviceToken); // SDK version 3.20.0 and above
                // Repro.setPushDeviceTokenString(deviceToken); // SDK version below 3.20.0 here
            });

            PushNotificationIOS.requestPermissions();
        }
    }

    render() {
        ...
    }
}
```

##### NOTE
Objective-Cのサンプルコードは [react-native-push-notification公式](https://github.com/react-native-push-notification/ios?tab=readme-ov-file#update-appdelegateh) をご参照ください

#### リッチ通知の受信準備

リッチ通知を受信するための実装は、 [リッチプッシュ通知（iOS）](https://docs.repro.io/ja/dev/sdk/push-notification/ios.md#ios-receiving-rich-notification) をご覧ください。

### プッシュ通知の設定 (Android)

Android のプッシュ通知に関しては、React Native 公式のAPIが存在しないため、 [プッシュ通知（Android）](https://docs.repro.io/ja/dev/sdk/push-notification/android.md#android-full-push-noti-setup) に従ってネイティブコード側で実装してください。



### オプション：ユニバーサルリンク/アプリリンクを使用する



端末に表示されたプッシュ通知およびアプリ内メッセージに設定されたリンクをタップした際に実行されるURLには、ユニバーサルリンク（またはアプリリンクと呼ばれる）を指定することが可能です。
（簡単のため、以下ではこれらをユニバーサルリンクと呼びます）

アプリにてユニバーサルリンクの実行時の処理を追加するには、以下の通り実装を行う必要があります。
（ここで設定された動作は、プッシュ通知およびアプリ内メッセージ対し有効となります。）

#### ユニバーサルリンクのURLパターンを登録する

ユニバーサルリンクを利用するためには、まずユニバーサルリンクのURLのパターン（正規表現）を指定する必要があります。

##### NOTE
パターン（正規表現）に合致すると、プッシュ通知の開封時や、アプリ内メッセージの遷移先に設定されたURLに対して、後述のコールバック処理をキックします。

また、アプリ内メッセージでHTMLコンテンツを表示するとき、そのコンテンツ内で発生したリクエストに対してもユニバーサルリンクの判定が行われます。

この指定は、iOSの場合は `AppDelegate` または `.plist` ファイル、Androidの場合は `Application` 継承クラス または `AndroidManifest.xml` ファイルのどちらか一方に記述することで行うことができます。

```objc
// AppDelegate.m

#import <Repro/Repro.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [Repro addOpenUrlFilterRegEx:@"https://example\\.com/page/"];
    [Repro addOpenUrlFilterRegEx:@"your-domain\\.com/.+\?universal=true"];
    ...
}


// .plist file
/*
<dict>
    <key>RPROpenUrlFilterRegExList</key>
    <array>
        <string>https://example\.com/page/</string>
        <string>your-domain\.com/.+\?universal=true</string>
    </array>
    ...
</dict>
*/
```

```java
// MyApplication.java

import io.repro.android.Repro;

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        Repro.addOpenUrlFilterRegEx("https://example\\.com/page/");
        Repro.addOpenUrlFilterRegEx("your-domain\\.com/.+\\?universal=true");
        ...
    }
...
}


// AndroidManifest.xml
// To specify multiple URL patterns, enter them separated by commas.
<application>
    ...
    <meta-data
        android:name="io.repro.android.OpenUrlFilterRegExList"
        android:value="https://example\\.com/page/;your-domain\\.com/.+\\?universal=true">
    </meta-data>
</application>
```

```kotlin
// MyApplication.kt

import io.repro.android.Repro

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        Repro.addOpenUrlFilterRegEx("https://example\\.com/page/")
        Repro.addOpenUrlFilterRegEx("your-domain\\.com/.+\\?universal=true")
        ...
    }
    ...
}


// AndroidManifest.xml
// To specify multiple URL patterns, enter them separated by commas.
<application>
    ...
    <meta-data
        android:name="io.repro.android.OpenUrlFilterRegExList"
        android:value="https://example\\.com/page/;your-domain\\.com/.+\\?universal=true">
    </meta-data>
</application>
```

```swift
// AppDelegate.swift

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
{
    Repro.add(openUrlFilterRegEx: "https://example\\.com/page/")
    Repro.add(openUrlFilterRegEx: "your-domain\\.com/.+\\?universal=true")
    ...
}

// .plist file
/*
<dict>
    <key>RPROpenUrlFilterRegExList</key>
    <array>
        <string>https://example\.com/page/</string>
        <string>your-domain\.com/.+\?universal=true</string>
    </array>
    ...
</dict>
*/
```

```dart
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

```csharp
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

```cpp
// YourAppNameScene.cpp

bool YourAppName::init() {
    ReproCpp::addOpenUrlFilterRegEx("https://example\\.com/page/");
    ReproCpp::addOpenUrlFilterRegEx("your-domain\\.com/.+\\?universal=true");
    ...
}
```

```js-cordova
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

```js-react-native
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

##### WARNING
ユニバーサルリンクとして設定するURLパターンは、可能な限り **ドメインとパスまで含めて具体的に指定** し、 **全て小文字で指定** してください。

もし、 https のようにスキームのみを指定した場合、アプリ内メッセージで表示された画面内で実行されたスクリプトなどによるリクエストもユニバーサルリンクと誤って判定され、意図しないタイミングでコールバック処理が実行される可能性があります。

また、URLパターンのスキーム/ドメイン部分に大文字を使用した場合、HTMLアプリ内メッセージで表示したボタンからユニバーサルリンクを使って遷移させようとするときに、スキーム/ドメイン部分が自動的に小文字に変換されて処理されます。パターン（正規表現）に一致せず、意図したタイミングでコールバック処理が実行されない可能性があります。

#### ユニバーサルリンク実行時の処理を登録する

次に、ユニバーサルリンクが実行された際に動作するコールバック処理を実装します。
処理内には、例えばURLのパターンに応じて画面遷移を行う動作などを記述します。

```objc
#import <Repro/Repro.h>

...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [Repro setOpenUrlCallback:^(NSURL *url) {
        if ([url.host isEqualToString:@"example.com"]) {
            // In case of your universal link perform navigation, present content, ...
            handleUniversalLink(url);
        }
    }];

    ...
    [Repro setup:@"YOUR_APP_TOKEN"];
    ...
}
```

```swift
// Set a callback that is executed everytime an URL is about to be opened
Repro.setOpenUrlCallback { url in
    if url.host == "example.com" {
        // In case of your universal link perform navigation, present content, ...
        handleUniversalLink(url)
    }
}
...
Repro.setup(token: "YOUR_APP_TOKEN")
...
```

```java
import io.repro.android.Repro;

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        // In order to execute a callback when a push notification is tapped,
        // the callback must be set in Application, not Activity.
        Repro.setOpenUrlCallback(new Repro.OpenUrlCallback() {
            // ** This callback method is executed in the main thread **
            @Override
            public void onOpened(Uri uri) {
                if ("example.com".equals(uri.getHost())) {
                    // In case of your universal link perform navigation, present content, ...
                }
            }
        });

        ...
        Repro.setup(this, YOUR_APP_TOKEN);
        ...
    }
    ...
}
```

```kotlin
import io.repro.android.Repro

class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        // In order to execute a callback when a push notification is tapped,
        // the callback must be set in Application, not Activity.
        Repro.setOpenUrlCallback { uri ->
            // ** This callback method is executed in the main thread **
            if (uri.host == "example.com") {
                // In case of your universal link perform navigation, present content, ...
            }
        }

        ...
        Repro.setup(this, "YOUR_APP_TOKEN")
        ...
    }
    ...
}
```

```dart
Repro.setOpenUrlCallback((uri) { // uri is of type Uri
   debugPrint("Universal Link Callback Handler received: " + uri.toString());
});
```

```csharp
// Somewhere before Repro.Setup(...)
Repro.SetOpenUrlCallback(uri => // uri is of type Uri
{
    Debug.Log("Universal Link Callback Handler received: " + uri.ToString());
});
```

```cpp
bool YourAppName::init() {
    ReproCpp::addOpenUrlFilterRegEx(...);

    ReproCpp::setOpenUrlCallback([](const char *url) {
        if (strcmp(url, "example.com") == 0) {
            // In case of your universal link perform navigation, present content, ...
        }
    });

    ReproCpp::setup("YOUR_APP_TOKEN")
    ...
}
```

```js-cordova
Repro.setOpenUrlCallback(function(url) { // url is of type String
    alert('Universal Link Callback Handler received: ' + url);
    if (url.includes("http://example.org")) {
        // In case of your universal link perform navigation, present content, ...
    }
});
```

```js-react-native
Repro.setOpenUrlCallback( (url) => {  // url is of type String
    console.log('Universal Link Callback Handler received: ' + url);
    if (url.includes("http://example.org")) {
        // In case of your universal link perform navigation, present content, ...
    }
});
```

---

js-expo

## プッシュ通知 (Expo)

### FCMの設定 (Android)

[FCMの設定 (Android)](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md) を参考に、Firebaseプロジェクトの設定を行ってください。

### APNs証明書の設定 (iOS)

[APNs証明書の設定 (iOS)](https://docs.repro.io/ja/dev/sdk/push-notification/setup-ios.md) を参考に、APNs証明書をRepro管理画面に登録してください。

### React Native Firebase をインストールする (Android)

Repro ではプッシュ通知を受信する際、Android 環境では Firebase Cloud Messaging を利用しています。
この利用のため、React Native Firebase を導入してください。

```sh
npm install @react-native-firebase/app
npm install @react-native-firebase/messaging
```

導入方法の詳細は以下を参考にしてください。

- [React Native Firebase](https://rnfirebase.io/)
- [Cloud Messaging | React Native Firebase](https://rnfirebase.io/messaging/usage)

### React Native Firebase の設定 (iOSプロジェクトを含む場合)

Android および iOS のプロジェクトを同時に開発している場合のみ、以下の設定を行ってください。

`expo-build-properties` をインストールしてください。

```sh
npx expo install expo-build-properties
```

また、 `app.json` 内に以下の項目を追加してください。

```json
{
    "expo": {
        "plugins": [
            [
                "expo-build-properties",
                {
                    "ios": {
                        "useFrameworks": "static"
                    }
                }
            ],
        ]
    }
}
```

### チャネルの設定を追加する (Android)

[app.json ファイルを編集する](https://docs.repro.io/ja/dev/sdk/getstarted/expo.md#expo-edit-app-json) を参考に、`app.json` ファイルにプッシュ通知のチャネルの設定を追加してください。

また必要に応じてその他の項目も設定してください。

### google-services.json ファイルを配置する (Android)

[FCMの設定 (Android)](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md) を参考に、Firebase Console から `google-services.json` ファイルをダウンロードしてください。

次に、ダウンロードした `google-services.json` ファイルをプロジェクトの `assets` ディレクトリにコピーしてください。

その後、プロジェクト内 `app.json` の `expo.android` に `"googleServicesFile": "./assets/google-services.json"` を追記してください。

```json
{
    "expo": {
        "android": {
            "googleServicesFile": "./assets/google-services.json"
        }
    }
}
```

### Expo Notifications をインストールする (iOS/Android)

プロジェクトに対し、以下の通り Expo Notifications をインストールしてください。

```sh
npx expo install expo-notifications
```

### Entitlementsの設定を行う (iOS)

プロジェクト内 `app.json` の `expo.ios` に `"entitlements": "aps-environment"` を追記してください。

`aps-environment` の値は環境によって適宜変更してください。

```json
{
    "expo": {
        "ios": {
            "entitlements": {
                "aps-environment": "development"
            }
        }
    }
}
```

### プッシュトークンをReproに送信する処理を実装する (iOS/Android)

プッシュ通知の宛先を指定するためにプッシュトークンをReproに送信します。

デバイストークンを取得する処理を追加し、 `Repro.setPushToken` を利用し値をセットしてください。

```js-expo
import { useEffect } from 'react';
import * as Notifications from 'expo-notifications';
import Repro from 'react-native-repro';

...

useEffect(() => {
    Notifications.getDevicePushTokenAsync().then(token => {
        Repro.setPushToken(token.data);
    })
    .catch((e) => {
        ...
    });
    ...
});
```

### アプリケーションのネイティブコードを生成する (iOS/Android)

以下のコマンドを実行し、アプリケーションをビルドしてください。

```sh
npx expo prebuild --clean
```

その他の実装方法については、 [開発ガイド](https://docs.repro.io/ja/dev/index.md) のReact Native 向けの解説を参照してください。

---

js-expo

## 導入: React Native (Expo)

##### NOTE
本ページでは、Expo (Managed Workflow) を利用する場合の導入方法を紹介しています。React Native で Expo を利用しない場合 または Bare Workflow で開発を行う場合の方法は [導入: React Native](https://docs.repro.io/ja/dev/sdk/getstarted/react-native.md) を参照してください。

### Expo Plugin のインストール

プロジェクトに対し、以下の通りパッケージをインストールしてください。

```sh
npx expo install react-native-repro
npx expo install expo-repro
```



### app.json ファイルを編集する

以下のようにプロジェクトの app.json ファイルに設定を記述してください。

```json
{
    "expo": {
        "plugins": [
            [
                "expo-repro",
                {
                    "sdkToken": "00000000-0000-0000-0000-000000000000"
                }
            ]
        ]
    }
}
```

| キー | データ型 | 概要 | 詳細 |
| --- | --- | --- | --- |
| `sdkToken` | String | アプリで使用するSDKトークン | 管理画面の 設定 > プロジェクト設定 に記載されている SDK トークン を設定してください。 **設定は必須です。** |
| `logLevel` | String | ログレベル | デフォルトで info レベルが設定されています。変更する場合のみ指定が必要です。設定可能な値は “debug”, “info”, “warn”, “error” のいずれかです。 |
| `endUserOptInDefault` | Boolean | オプトイン/オプトアウト初期状態の指定 | デフォルトで “true”（初期状態でオプトイン）が設定されています。変更する場合のみ指定が必要です。 |
| `advertisingIdentifierCollectionEnabled` | Boolean | 広告ID取得設定 | デフォルトで “false”（取得しない）が設定されています。広告ID（AAIDおよびIDFA）の取得を行う場合のみ “true” を指定してください。 |
| `openUrlFilterRegExList` | Array(String) | ユニバーサルリンクのURLパターン | ユニバーサルリンク機能を使用する際に指定が必要なURLパターンを設定します。この機能を使用する場合のみ記述してください。詳細は [プッシュ通知（iOS）](https://docs.repro.io/ja/dev/sdk/push-notification/ios.md) を参照してください。 |
| `iosHtmlInAppBaseUrl` | String | HTMLアプリ内メッセージのベースURL | デフォルトで `https://io.repro.repro` が設定されています。変更する場合のみ指定が必要です。詳細は [App-Bound Domains を有効にしている場合（iOSのみ）](https://docs.repro.io/ja/dev/sdk/in-app-message.md#html-inapp-message-custom-base-url) を参照してください。 |
| `androidPushNotificationChannelId` | String | プッシュ通知のチャネルID | プッシュ通知のチャネルIDを設定します。プッシュ通知機能を利用する場合のみ指定してください。（プッシュ通知機能を利用しない場合は、この項目を設定しないでください） |
| `androidPushNotificationChannelName` | String | Android用 プッシュ通知のチャネル名 | プッシュ通知のチャネル名を設定します。プッシュ通知機能を利用する場合のみ指定してください。 |
| `androidPushNotificationChannelDescription` | String | Android用 プッシュ通知のチャネルの説明 | プッシュ通知のチャネルの説明を設定します。プッシュ通知機能を利用する場合のみ指定してください。 |
| `androidPushNotificationShowBadge` | Boolean | Android用 プッシュ通知受信時のバッジ機能の利用可否の指定 | プッシュ通知のバッジ表示可否を設定します。プッシュ通知機能を利用する場合のみ指定してください。デフォルトで “true” が設定されています。 |

### アプリケーションのネイティブコードを生成する

以下のコマンドを実行し、アプリケーションをビルドしてください。

```sh
npx expo prebuild --clean
```

#### React Native で Repro をインポートする

JavaScript のコード内で下記のように Repro をインポートしてください：

```js-expo
import Repro from 'react-native-repro';
```

これにより、 JavaScript のコード内から `Repro` オブジェクトのメソッドを呼び出せます：

```js-expo
Repro.track("user review", { rating: 3 });
```

SDKが収集した情報は定期的にサーバーにアップロードされます。

### イベントをトラックする

意味のある分析や、マーケティング施策を実施するためには、適切なユーザーグループを絞り込むことが重要です。イベントをトラックしてユーザーの行動を記録することにより、管理画面上で目的に応じた適切なユーザーグループを選択することができるようになります。

イベントを用いたユーザーグループ指定の例:

- [キャンペーンの作成画面で、イベントやユーザープロフィールを組み合わせて、配信対象となるユーザーグループを指定する](https://docs.repro.io/ja/dashboard/campaign/target.md)

どういうイベントをとるべきかわからない場合は、まず各画面の表示時にイベントをとってみることをおすすめします。

例:

```objc
@implementation MainViewController

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [Repro track:@"MainViewController" properties:nil];

    ...
}
```

```swift
class MainViewController: UIViewController {

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        Repro.track(event: "MainViewController", properties: [:])

        ...
    }
```

```java
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onResume() {
        super.onResume();
        Repro.track("MainActivity");

        ...
    }
}
```

```kotlin
class MainActivity : AppCompatActivity() {

    override fun onResume() {
        super.onResume()
        Repro.track("MainActivity")

        ...
    }
}
```

```cpp
#include "ReproCpp.h"

...

ReproCpp::track("Initialized");
```

```csharp
Repro.Track ("Initialized");
```

```js-cordova
// Will be written later
```

```js-react-native
class MainScreen extends React.Component {

    componentDidMount() {
        Repro.track("MainScreen", {});
    }

    ...
 }
```

```js-expo
import Repro from 'react-native-repro';

...

Repro.track("MainScreen", {});
```

```dart
import 'package:repro_flutter/repro.dart';

...

await Repro.track("Initialized");
```

### ユーザーIDをセットする

Repro では分析結果はユーザー単位で集計しています。ユーザーIDをセットすることにより、下記のメリットがあります:

- 複数のデバイスを使っているユーザーを同一視できる
- キャンペーンの配信対象の抽出がより精緻になる

詳しくは [こちら](https://docs.repro.io/ja/dev/sdk/user-id.md) をご覧ください。

### プッシュ通知を配信する

Reproでは、管理画面もしくはAPIからプッシュ通知配信をすることができます。プッシュ通知配信をするための実装は [こちら](https://docs.repro.io/ja/dev/sdk/push-notification/index.md) をご覧ください。

### Next...

その他の機能についての詳細は、以下をご覧ください。

- [セッション・ライフサイクル](https://docs.repro.io/ja/dev/sdk/session.md)
- [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md)
- [ユーザーID](https://docs.repro.io/ja/dev/sdk/user-id.md)
- [デバイスID](https://docs.repro.io/ja/dev/sdk/device-id.md)
- [ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md)
- [WebView](https://docs.repro.io/ja/dev/sdk/webview.md)
- [オプトアウト機能](https://docs.repro.io/ja/dev/sdk/optout/index.md)
- [アプリ内メッセージ](https://docs.repro.io/ja/dev/sdk/in-app-message.md)
- [プッシュ通知](https://docs.repro.io/ja/dev/sdk/push-notification/index.md)
- [Adjustで取得したアトリビューションデータをReproにセットする](https://docs.repro.io/ja/dev/sdk/integrate-adjust.md)
- [AppsFlyerで取得したアトリビューションデータをReproにセットする](https://docs.repro.io/ja/dev/sdk/integrate-appsflyer.md)

---

js-react-native, objc, swift, java, kotlin

## 導入: React Native

### React Native SDK のインストール

##### NOTE
本ページでは、Expo を使用しない場合 および Bare Workflow で Expo を利用する場合の導入方法を紹介しています。
Expo (Managed Workflow) で開発を行う場合の方法は [導入: React Native (Expo)](https://docs.repro.io/ja/dev/sdk/getstarted/expo.md) を参照してください。

##### NOTE
Reproでは React Native のバージョン **0.41.2** 以上を推奨しています。

##### NOTE
`react-native init` ではなく、 `create-react-native-app` もしくは `expo init` を利用してプロジェクトを作成した場合は、プロジェクトを **eject** する必要があります。詳細な手順については、ご利用のビルド環境に応じたドキュメントを参照ください。 [Expo のサンプル](https://docs.expo.io/versions/latest/expokit/eject/)

##### NOTE
New Architecture を有効にしている場合、 React Native SDK はバージョン4.0.0以上をご利用ください。

React Native プロジェクトが下記のようなディレクトリ構造となっていることをご確認ください：

```
<PROJECT_ROOT>
├── app.json
├── package.json
├── node_modules
│   └── ...
├── android
│   ├── ...
│   └── build.gradle
└── ios
    ├── ...
    └── <APP_NAME>.xcodeproj
```

下記のコマンドで Repro の React Native SDK をインストールしてください：

### React Native 0.60.0以上

```sh
$ npm install react-native-repro --save
```

#### iOSプロジェクトへの導入

```sh
$ cd ios

$ pod install
```

#### Androidプロジェクトへの導入

`android/build.gradle` を開き、下記の設定を追加してください：

```groovy
 allprojects {
     repositories {
         ...
         maven {
             url "$rootDir/../node_modules/react-native-repro/sdk-android"
         }
     }
 }
```

### React Native 0.60.0未満

```sh
$ npm install react-native-repro --save

$ react-native link repro-react-native
```

#### iOSプロジェクトへの導入（CocoaPodsを利用している場合）

```sh
$ cd ios

$ pod install
```

#### iOSプロジェクトへの導入（CocoaPodsを利用していない場合）

プロジェクトがCocoaPodsを利用していない場合のみ、ReproをXcodeプロジェクトに手動で追加する必要があります。次の2つのステップを実施してください。

##### Framework Pathの設定

次に、 **Project Setting > メインプロジェクトのTarget > Build Settings** を開き、 **Framework Search Path** を選択し、下記のパスを追加してください：

`$(PROJECT_DIR)/../node_modules/react-native-repro/sdk-ios/`

#### Androidプロジェクトへの導入

`android/build.gradle` を開き、下記の設定を追加してください：

```groovy
 allprojects {
     repositories {
         ...
         maven {
             url "$rootDir/../node_modules/react-native-repro/sdk-android"
         }
     }
 }
```

### セットアップ

#### iOS

`Repro` を `AppDelegate` でインポートし、 `application:didFinishLaunchingWithOptions:` で [セッション](https://docs.repro.io/ja/dev/sdk/session.md) を開始してください。 `Repro setup` は React Native の初期化処理より前に呼び出す必要があります。

`YOUR_APP_TOKEN` には管理画面の **設定 > プロジェクト設定 > 認証情報** に記載されている **SDK トークン** を設定してください。

```js-react-native
// This section explains the implementation in iOS.
// Please change the language to Objective-C or Swift.
```

```objc
#import <Repro/Repro.h>

...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Setup Repro
    [Repro setup:@"YOUR_APP_TOKEN"];

    // ... react-native javascript setup code ...
    return YES;
}
```

```swift
import Repro

...

override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool
{
    // Setup Repro
    Repro.setup(token: "YOUR_APP_TOKEN")

    // ... react-native javascript setup code ...
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
```

```java
// This section explains the implementation in iOS.
// Please change the language to Objective-C or Swift.
```

```kotlin
// This section explains the implementation in iOS.
// Please change the language to Objective-C or Swift.
```

#### Android

`MainApplication` を開き、Applicationの `onCreate` メソッドで新しい [セッション](https://docs.repro.io/ja/dev/sdk/session.md) を開始してください。`Repro setup` は React Native の初期化処理より前に呼び出す必要があります。

`YOUR_APP_TOKEN` には管理画面の **設定 > プロジェクト設定 > 認証情報** に記載されている **SDK トークン** を設定してください。

```js-react-native
// This section explains the implementation in android.
// Please change the language to Java or Kotlin.
```

```objc
// This section explains the implementation in android.
// Please change the language to Java or Kotlin.
```

```swift
// This section explains the implementation in android.
// Please change the language to Java or Kotlin.
```

```java
import io.repro.android.Repro;

public class MainApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        // Setup Repro
        Repro.setup(this, "YOUR_APP_TOKEN");

        // SoLoader.init(...) and other react-native javascript setup code ...
    }
}
```

```kotlin
import io.repro.android.Repro

class MainApplication : Application(), ReactApplication {

    override fun onCreate() {
        super.onCreate()
        // Setup Repro
        Repro.setup(this, "YOUR_APP_TOKEN")

        // SoLoader.init(...) and other react-native javascript setup code ...
    }
}
```

#### React Native で Repro をインポートする

JavaScript のコード内で下記のように Repro をインポートしてください：

```js-react-native
import Repro from 'react-native-repro';
```

```objc
// This section explains the implementation in React Native.
// Please change the language to JavaScript(React Native).
```

```swift
// This section explains the implementation in React Native.
// Please change the language to JavaScript(React Native).
```

```java
// This section explains the implementation in React Native.
// Please change the language to JavaScript(React Native).
```

```kotlin
// This section explains the implementation in React Native.
// Please change the language to JavaScript(React Native).
```

これにより、 JavaScript のコード内から `Repro` オブジェクトのメソッドを呼び出せます：

```js-react-native
Repro.track("user review", { rating: 3 });
```

```objc
// This section explains the implementation in React Native.
// Please change the language to JavaScript(React Native).
```

```swift
// This section explains the implementation in React Native.
// Please change the language to JavaScript(React Native).
```

```java
// This section explains the implementation in React Native.
// Please change the language to JavaScript(React Native).
```

```kotlin
// This section explains the implementation in React Native.
// Please change the language to JavaScript(React Native).
```

SDKが収集した情報は定期的にサーバーにアップロードされます。

### イベントをトラックする

意味のある分析や、マーケティング施策を実施するためには、適切なユーザーグループを絞り込むことが重要です。イベントをトラックしてユーザーの行動を記録することにより、管理画面上で目的に応じた適切なユーザーグループを選択することができるようになります。

イベントを用いたユーザーグループ指定の例:

- [キャンペーンの作成画面で、イベントやユーザープロフィールを組み合わせて、配信対象となるユーザーグループを指定する](https://docs.repro.io/ja/dashboard/campaign/target.md)

どういうイベントをとるべきかわからない場合は、まず各画面の表示時にイベントをとってみることをおすすめします。

例:

```objc
@implementation MainViewController

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [Repro track:@"MainViewController" properties:nil];

    ...
}
```

```swift
class MainViewController: UIViewController {

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        Repro.track(event: "MainViewController", properties: [:])

        ...
    }
```

```java
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onResume() {
        super.onResume();
        Repro.track("MainActivity");

        ...
    }
}
```

```kotlin
class MainActivity : AppCompatActivity() {

    override fun onResume() {
        super.onResume()
        Repro.track("MainActivity")

        ...
    }
}
```

```cpp
#include "ReproCpp.h"

...

ReproCpp::track("Initialized");
```

```csharp
Repro.Track ("Initialized");
```

```js-cordova
// Will be written later
```

```js-react-native
class MainScreen extends React.Component {

    componentDidMount() {
        Repro.track("MainScreen", {});
    }

    ...
 }
```

```js-expo
import Repro from 'react-native-repro';

...

Repro.track("MainScreen", {});
```

```dart
import 'package:repro_flutter/repro.dart';

...

await Repro.track("Initialized");
```

### ユーザーIDをセットする

Repro では分析結果はユーザー単位で集計しています。ユーザーIDをセットすることにより、下記のメリットがあります:

- 複数のデバイスを使っているユーザーを同一視できる
- キャンペーンの配信対象の抽出がより精緻になる

詳しくは [こちら](https://docs.repro.io/ja/dev/sdk/user-id.md) をご覧ください。

### プッシュ通知を配信する

Reproでは、管理画面もしくはAPIからプッシュ通知配信をすることができます。プッシュ通知配信をするための実装は [こちら](https://docs.repro.io/ja/dev/sdk/push-notification/index.md) をご覧ください。

### Next...

その他の機能についての詳細は、以下をご覧ください。

- [セッション・ライフサイクル](https://docs.repro.io/ja/dev/sdk/session.md)
- [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md)
- [ユーザーID](https://docs.repro.io/ja/dev/sdk/user-id.md)
- [デバイスID](https://docs.repro.io/ja/dev/sdk/device-id.md)
- [ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md)
- [WebView](https://docs.repro.io/ja/dev/sdk/webview.md)
- [オプトアウト機能](https://docs.repro.io/ja/dev/sdk/optout/index.md)
- [アプリ内メッセージ](https://docs.repro.io/ja/dev/sdk/in-app-message.md)
- [プッシュ通知](https://docs.repro.io/ja/dev/sdk/push-notification/index.md)
- [Adjustで取得したアトリビューションデータをReproにセットする](https://docs.repro.io/ja/dev/sdk/integrate-adjust.md)
- [AppsFlyerで取得したアトリビューションデータをReproにセットする](https://docs.repro.io/ja/dev/sdk/integrate-appsflyer.md)

---

## 開発ガイド

* [アカウント作成](https://docs.repro.io/ja/dev/repro-account.md)
  * [Repro アカウントを作成](https://docs.repro.io/ja/dev/repro-account.md#repro)
  * [SDK の導入](https://docs.repro.io/ja/dev/repro-account.md#sdk)
* [iOS/Android SDK](https://docs.repro.io/ja/dev/sdk/index.md)
  * [導入](https://docs.repro.io/ja/dev/sdk/getstarted/index.md)
  * [セッション・ライフサイクル](https://docs.repro.io/ja/dev/sdk/session.md)
  * [ユーザーID](https://docs.repro.io/ja/dev/sdk/user-id.md)
  * [デバイスID](https://docs.repro.io/ja/dev/sdk/device-id.md)
  * [ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md)
  * [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md)
  * [プッシュ通知](https://docs.repro.io/ja/dev/sdk/push-notification/index.md)
  * [ニュースフィード](https://docs.repro.io/ja/dev/sdk/newsfeed.md)
  * [アプリ内メッセージ](https://docs.repro.io/ja/dev/sdk/in-app-message.md)
  * [シルバーエッグレコメンドメッセージ](https://docs.repro.io/ja/dev/sdk/silver-egg-recommend-in-app-message.md)
  * [アプリ内パラメーター](https://docs.repro.io/ja/dev/sdk/remote-config.md)
  * [WebView](https://docs.repro.io/ja/dev/sdk/webview.md)
  * [オプトアウト機能](https://docs.repro.io/ja/dev/sdk/optout/index.md)
  * [広告ID取得設定](https://docs.repro.io/ja/dev/sdk/ad-id.md)
  * [QRコードを用いてオーディエンスにユーザーを登録する](https://docs.repro.io/ja/dev/sdk/qr-code.md)
  * [Adjustで取得したアトリビューションデータをReproにセットする](https://docs.repro.io/ja/dev/sdk/integrate-adjust.md)
  * [AppsFlyerで取得したアトリビューションデータをReproにセットする](https://docs.repro.io/ja/dev/sdk/integrate-appsflyer.md)
  * [ReproへのLINEユーザーIDの登録 (iOS/Android SDK)](https://docs.repro.io/ja/dev/sdk/line-integration.md)
  * [ログレベル](https://docs.repro.io/ja/dev/sdk/log.md)
  * [検証方法](https://docs.repro.io/ja/dev/sdk/tests/index.md)
* [Web](https://docs.repro.io/ja/dev/web/index.md)
  * [導入](https://docs.repro.io/ja/dev/web/getstarted/web.md)
  * [ユーザーID](https://docs.repro.io/ja/dev/web/user-id.md)
  * [ユーザープロフィール](https://docs.repro.io/ja/dev/web/user-profile.md)
  * [ReproへのLINEユーザーIDの登録 (Web SDK)](https://docs.repro.io/ja/dev/web/line-integration.md)
  * [イベントトラッキング](https://docs.repro.io/ja/dev/web/tracking.md)
  * [セッション・ライフサイクル](https://docs.repro.io/ja/dev/web/session.md)
  * [デバイスID](https://docs.repro.io/ja/dev/web/device-id.md)
  * [オプトアウト機能](https://docs.repro.io/ja/dev/web/optout.md)
  * [バージョン1 から バージョン2 への更新手順](https://docs.repro.io/ja/dev/web/migration.md)
  * [API](https://docs.repro.io/ja/dev/web/api.md)
  * [クロスドメイン・トラッキング機能](https://docs.repro.io/ja/dev/web/cross-domain-tracking.md)
  * [WebViewでの動作について](https://docs.repro.io/ja/dev/web/webview.md)
  * [SPA(Single Page Application)サイトへの導入](https://docs.repro.io/ja/dev/web/spa.md)
  * [Webプッシュ通知](https://docs.repro.io/ja/dev/web/web-push-notification.md)
  * [Repro Webの計測タグが正しく動いているか確認する](https://docs.repro.io/ja/dev/web/measurement-tag.md)
  * [Repro Webの利用するCookieについて](https://docs.repro.io/ja/dev/web/cookies.md)
* [オーディエンスAPI](https://docs.repro.io/ja/dev/audience-api/index.md)
  * [はじめに](https://docs.repro.io/ja/dev/audience-api/index.md#id1)
  * [オーディエンスAPI v3](https://docs.repro.io/ja/dev/audience-api/index.md#api-v3)
  * [オーディエンスAPI v2(廃止)](https://docs.repro.io/ja/dev/audience-api/index.md#api-v2)
* [オーディエンスインポート(β)](https://docs.repro.io/ja/dev/audience-import/index.md)
  * [はじめに](https://docs.repro.io/ja/dev/audience-import/index.md#id2)
  * [ファイル仕様](https://docs.repro.io/ja/dev/audience-import/index.md#id3)
  * [取り込み頻度](https://docs.repro.io/ja/dev/audience-import/index.md#id4)
* [プッシュAPI](https://docs.repro.io/ja/dev/push-api/index.md)
  * [はじめに](https://docs.repro.io/ja/dev/push-api/index.md#id1)
  * [API経由でプッシュ通知を配信する](https://docs.repro.io/ja/dev/push-api/index.md#id2)
  * [APIフォーマット](https://docs.repro.io/ja/dev/push-api/index.md#push-api-format)
  * [管理画面から通知を配信する](https://docs.repro.io/ja/dev/push-api/index.md#id15)
  * [プッシュAPIのリクエスト](https://docs.repro.io/ja/dev/push-api/index.md#push-api-request)
  * [プッシュAPIのレスポンス](https://docs.repro.io/ja/dev/push-api/index.md#push-api-response)
* [イベントバルクトラッキング (β)](https://docs.repro.io/ja/dev/event-bulk-tracking/index.md)
  * [参考](https://docs.repro.io/ja/dev/event-bulk-tracking/index.md#id2)
  * [はじめに](https://docs.repro.io/ja/dev/event-bulk-tracking/index.md#id3)
  * [利用方法](https://docs.repro.io/ja/dev/event-bulk-tracking/index.md#id10)
  * [処理内容](https://docs.repro.io/ja/dev/event-bulk-tracking/index.md#id14)
  * [制限事項](https://docs.repro.io/ja/dev/event-bulk-tracking/index.md#id15)
  * [その他](https://docs.repro.io/ja/dev/event-bulk-tracking/index.md#id16)
* [ユーザープロフィールAPI](https://docs.repro.io/ja/dev/user-profile-api/index.md)
  * [はじめに](https://docs.repro.io/ja/dev/user-profile-api/index.md#id1)
  * [API 経由でユーザープロフィールを更新する](https://docs.repro.io/ja/dev/user-profile-api/index.md#id2)
  * [ユーザープロフィールAPIのリクエスト](https://docs.repro.io/ja/dev/user-profile-api/index.md#user-profile-api-request)
  * [ユーザープロフィールAPIのレスポンス](https://docs.repro.io/ja/dev/user-profile-api/index.md#user-profile-api-response)
* [ユーザープロフィールバルクインポート](https://docs.repro.io/ja/dev/user-profile-bulk-import-api/index.md)
  * [はじめに](https://docs.repro.io/ja/dev/user-profile-bulk-import-api/index.md#id2)
  * [管理画面アップロード](https://docs.repro.io/ja/dev/user-profile-bulk-import-api/index.md#user-profile-bulk-import-via-dashboard)
  * [S3アップロード](https://docs.repro.io/ja/dev/user-profile-bulk-import-api/index.md#s3)
  * [ユーザープロフィールバルクインポートAPI v3](https://docs.repro.io/ja/dev/user-profile-bulk-import-api/index.md#api-v3)
  * [(廃止予定)ユーザープロフィールバルクインポートAPI v2](https://docs.repro.io/ja/dev/user-profile-bulk-import-api/index.md#api-v2)
* [ニュースフィードAPI](https://docs.repro.io/ja/dev/newsfeed-api/index.md)
  * [はじめに](https://docs.repro.io/ja/dev/newsfeed-api/index.md#id1)
  * [ニュースフィードAPI](https://docs.repro.io/ja/dev/newsfeed-api/index.md#id3)
* [削除ユーザー登録API](https://docs.repro.io/ja/dev/user-data-deletions-api/index.md)
  * [はじめに](https://docs.repro.io/ja/dev/user-data-deletions-api/index.md#id1)
  * [削除したいユーザーを登録する](https://docs.repro.io/ja/dev/user-data-deletions-api/index.md#id2)
  * [削除ユーザー登録APIのリクエスト](https://docs.repro.io/ja/dev/user-data-deletions-api/index.md#user-data-deletions-api-request)
  * [削除ユーザー登録APIのレスポンス](https://docs.repro.io/ja/dev/user-data-deletions-api/index.md#user-data-deletions-api-response)
  * [削除が完了した時にメールを受信する](https://docs.repro.io/ja/dev/user-data-deletions-api/index.md#id10)
* [メール](https://docs.repro.io/ja/dev/mail/index.md)
  * [配信前準備の概要](https://docs.repro.io/ja/dev/mail/getstarted.md)
  * [迷惑メール対策](https://docs.repro.io/ja/dev/mail/anti-spam.md)
  * [メールチャネル設定](https://docs.repro.io/ja/dev/mail/email-channel.md)
  * [Reproへのメールアドレス連携方法](https://docs.repro.io/ja/dev/mail/email-address-integration.md)
  * [配信リスト整備](https://docs.repro.io/ja/dev/mail/email-address-management.md)
  * [メール配信のウォームアップ](https://docs.repro.io/ja/dev/mail/warmup.md)

---

## アカウント作成

### Repro アカウントを作成

アカウントの作成をご希望される場合は、 [サービスに関するお問い合わせ](https://repro.io/contact/) までお問い合わせください。

### SDK の導入

お使いのプラットフォームに従い、SDKの導入を進めてください。

* [iOS](https://docs.repro.io/ja/dev/sdk/getstarted/ios.md)
* [Android](https://docs.repro.io/ja/dev/sdk/getstarted/android.md)
* [Unity](https://docs.repro.io/ja/dev/sdk/getstarted/unity.md)
* [Cordova](https://docs.repro.io/ja/dev/sdk/getstarted/cordova.md)
* [Monaca](https://docs.repro.io/ja/dev/sdk/getstarted/monaca.md)
* [Cocos2d-x](https://docs.repro.io/ja/dev/sdk/getstarted/cocos2d-x.md)
* [React Native](https://docs.repro.io/ja/dev/sdk/getstarted/react-native.md)
* [React Native (Expo)](https://docs.repro.io/ja/dev/sdk/getstarted/expo.md)
* [Flutter](https://docs.repro.io/ja/dev/sdk/getstarted/flutter.md)
* [Web](https://docs.repro.io/ja/dev/web/getstarted/web.md)

---

js

## 導入: Cordova

### Cordova Plugin のインストール

最新版のcordova pluginをインストールする場合、Cordova CLI (もしくはPhoneGap CLI) 6.5以上及びCordova Android 6.4以上が必要です。バージョンをご確認の上、以下のコマンドを実行してください。

```sh
# cordova
$ cordova plugin add cordova-plugin-repro

# phonegap
$ phonegap plugin add cordova-plugin-repro
```

##### NOTE
Firebaseの依存バージョンを変更するためには、Cordova Pluginのインストール時にオプションの指定が必要です。
詳細は [オプション：Firebaseの依存バージョンを変更する](https://docs.repro.io/ja/dev/sdk/push-notification/cordova.md#cordova-change-firebase-version) を参照してください。

### セットアップ

`index.js` の `onDeviceReady` で [セッション](https://docs.repro.io/ja/dev/sdk/session.md) を開始してください。

`YOUR_APP_TOKEN` には管理画面の **設定 > プロジェクト設定 > 認証情報** に記載されている **SDK トークン** を設定してください。

```js
onDeviceReady: function() {
    app.receivedEvent('deviceready');

    ...

    // Setup Repro
    Repro.setup("YOUR_APP_TOKEN");

    ...
},
```

SDKが収集した情報は定期的にサーバーにアップロードされます。

### イベントをトラックする

意味のある分析や、マーケティング施策を実施するためには、適切なユーザーグループを絞り込むことが重要です。イベントをトラックしてユーザーの行動を記録することにより、管理画面上で目的に応じた適切なユーザーグループを選択することができるようになります。

イベントを用いたユーザーグループ指定の例:

- [キャンペーンの作成画面で、イベントやユーザープロフィールを組み合わせて、配信対象となるユーザーグループを指定する](https://docs.repro.io/ja/dashboard/campaign/target.md)

どういうイベントをとるべきかわからない場合は、まず各画面の表示時にイベントをとってみることをおすすめします。

例:

```objc
@implementation MainViewController

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [Repro track:@"MainViewController" properties:nil];

    ...
}
```

```swift
class MainViewController: UIViewController {

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        Repro.track(event: "MainViewController", properties: [:])

        ...
    }
```

```java
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onResume() {
        super.onResume();
        Repro.track("MainActivity");

        ...
    }
}
```

```kotlin
class MainActivity : AppCompatActivity() {

    override fun onResume() {
        super.onResume()
        Repro.track("MainActivity")

        ...
    }
}
```

```cpp
#include "ReproCpp.h"

...

ReproCpp::track("Initialized");
```

```csharp
Repro.Track ("Initialized");
```

```js-cordova
// Will be written later
```

```js-react-native
class MainScreen extends React.Component {

    componentDidMount() {
        Repro.track("MainScreen", {});
    }

    ...
 }
```

```js-expo
import Repro from 'react-native-repro';

...

Repro.track("MainScreen", {});
```

```dart
import 'package:repro_flutter/repro.dart';

...

await Repro.track("Initialized");
```

### ユーザーIDをセットする

Repro では分析結果はユーザー単位で集計しています。ユーザーIDをセットすることにより、下記のメリットがあります:

- 複数のデバイスを使っているユーザーを同一視できる
- キャンペーンの配信対象の抽出がより精緻になる

詳しくは [こちら](https://docs.repro.io/ja/dev/sdk/user-id.md) をご覧ください。

### プッシュ通知を配信する

Reproでは、管理画面もしくはAPIからプッシュ通知配信をすることができます。プッシュ通知配信をするための実装は [こちら](https://docs.repro.io/ja/dev/sdk/push-notification/index.md) をご覧ください。

### Next...

その他の機能についての詳細は、以下をご覧ください。

- [セッション・ライフサイクル](https://docs.repro.io/ja/dev/sdk/session.md)
- [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md)
- [ユーザーID](https://docs.repro.io/ja/dev/sdk/user-id.md)
- [デバイスID](https://docs.repro.io/ja/dev/sdk/device-id.md)
- [ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md)
- [WebView](https://docs.repro.io/ja/dev/sdk/webview.md)
- [オプトアウト機能](https://docs.repro.io/ja/dev/sdk/optout/index.md)
- [アプリ内メッセージ](https://docs.repro.io/ja/dev/sdk/in-app-message.md)
- [プッシュ通知](https://docs.repro.io/ja/dev/sdk/push-notification/index.md)
- [Adjustで取得したアトリビューションデータをReproにセットする](https://docs.repro.io/ja/dev/sdk/integrate-adjust.md)
- [AppsFlyerで取得したアトリビューションデータをReproにセットする](https://docs.repro.io/ja/dev/sdk/integrate-appsflyer.md)

---

js

## 導入: Monaca

### Reproとの連携

Monaca IDEの **設定 > 外部サービス連携...** をクリックします。



Reproの **詳細を見る** をクリックします。



**インストール** をクリックします。



以上でReproのプラグインが導入されます。



### セットアップ

`index.html` の `onDeviceReady` で [セッション](https://docs.repro.io/ja/dev/sdk/session.md) を開始してください。

`YOUR_APP_TOKEN` には管理画面の **設定 > プロジェクト設定 > 認証情報** に記載されている **SDK トークン** を設定してください。

```js
function onDeviceReady() {
    ...

    if (typeof Repro != "undefined") {
        // Setup Repro
        Repro.setup("YOUR_APP_TOKEN");
    }

    ...
}
```

Reproの動作を確認するにはアプリを実機で動作させる必要があります。

**ビルド** ボタンをクリックし、 [Monaca アプリのビルド](http://docs.monaca.mobi/cur/ja/quick_start/cloud_ide/building_app/) に従ってMonacaアプリを実機で動作させてください。



SDKが収集した情報は定期的にサーバーにアップロードされます。

### イベントをトラックする

意味のある分析や、マーケティング施策を実施するためには、適切なユーザーグループを絞り込むことが重要です。イベントをトラックしてユーザーの行動を記録することにより、管理画面上で目的に応じた適切なユーザーグループを選択することができるようになります。

イベントを用いたユーザーグループ指定の例:

- [キャンペーンの作成画面で、イベントやユーザープロフィールを組み合わせて、配信対象となるユーザーグループを指定する](https://docs.repro.io/ja/dashboard/campaign/target.md)

どういうイベントをとるべきかわからない場合は、まず各画面の表示時にイベントをとってみることをおすすめします。

例:

```objc
@implementation MainViewController

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [Repro track:@"MainViewController" properties:nil];

    ...
}
```

```swift
class MainViewController: UIViewController {

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        Repro.track(event: "MainViewController", properties: [:])

        ...
    }
```

```java
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onResume() {
        super.onResume();
        Repro.track("MainActivity");

        ...
    }
}
```

```kotlin
class MainActivity : AppCompatActivity() {

    override fun onResume() {
        super.onResume()
        Repro.track("MainActivity")

        ...
    }
}
```

```cpp
#include "ReproCpp.h"

...

ReproCpp::track("Initialized");
```

```csharp
Repro.Track ("Initialized");
```

```js-cordova
// Will be written later
```

```js-react-native
class MainScreen extends React.Component {

    componentDidMount() {
        Repro.track("MainScreen", {});
    }

    ...
 }
```

```js-expo
import Repro from 'react-native-repro';

...

Repro.track("MainScreen", {});
```

```dart
import 'package:repro_flutter/repro.dart';

...

await Repro.track("Initialized");
```

### ユーザーIDをセットする

Repro では分析結果はユーザー単位で集計しています。ユーザーIDをセットすることにより、下記のメリットがあります:

- 複数のデバイスを使っているユーザーを同一視できる
- キャンペーンの配信対象の抽出がより精緻になる

詳しくは [こちら](https://docs.repro.io/ja/dev/sdk/user-id.md) をご覧ください。

### プッシュ通知を配信する

Reproでは、管理画面もしくはAPIからプッシュ通知配信をすることができます。プッシュ通知配信をするための実装は [こちら](https://docs.repro.io/ja/dev/sdk/push-notification/index.md) をご覧ください。

### Next...

その他の機能についての詳細は、以下をご覧ください。

- [セッション・ライフサイクル](https://docs.repro.io/ja/dev/sdk/session.md)
- [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md)
- [ユーザーID](https://docs.repro.io/ja/dev/sdk/user-id.md)
- [デバイスID](https://docs.repro.io/ja/dev/sdk/device-id.md)
- [ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md)
- [WebView](https://docs.repro.io/ja/dev/sdk/webview.md)
- [オプトアウト機能](https://docs.repro.io/ja/dev/sdk/optout/index.md)
- [アプリ内メッセージ](https://docs.repro.io/ja/dev/sdk/in-app-message.md)
- [プッシュ通知](https://docs.repro.io/ja/dev/sdk/push-notification/index.md)
- [Adjustで取得したアトリビューションデータをReproにセットする](https://docs.repro.io/ja/dev/sdk/integrate-adjust.md)
- [AppsFlyerで取得したアトリビューションデータをReproにセットする](https://docs.repro.io/ja/dev/sdk/integrate-appsflyer.md)

---

dart, objc, swift, java, kotlin

## 導入: Flutter

### Flutter Package のインストール

プロジェクト配下にある `pubspec.yaml` を開き、`dependencies` 欄に `repro_flutter` を追記します。

```yaml
dependencies:
  flutter:
    sdk: flutter
  ...
  repro_flutter: ^3.18.2
```

##### NOTE
- Flutter Package バージョン 3.0.0 以降は [Sound null safety 機能](https://dart.dev/null-safety) に対応したものとなります。
  したがって、Sound null safety 機能を利用していないアプリケーションにパッケージを導入する場合、バージョン 3.0.0 未満を使用してください。
- Flutter Package バージョン 3.14.0 以降は [Android v1 embedding](https://docs.flutter.dev/release/breaking-changes/android-v1-embedding-create-deprecation) の処理を削除したものとなります。
  したがって、Android v1 embedding を利用しているアプリケーションにパッケージを導入する場合、バージョン 3.14.0 未満を使用してください。

以下のコマンドを実行して、Repro の Flutter Plugin をインストールします。

```sh
$ flutter packages get
```

#### iOS プロジェクトへの導入

プロジェクトのルートディレクトリで、以下のコマンドを実行してください。

```sh
$ cd ios
$ pod install
```

#### Android プロジェクトへの導入

アプリケーションの `app/build.gradle` または `app/build.gradle.kts` を開き、以下の設定を追加してください。

**build.gradle (Groovy)**

```groovy
dependencies {
  implementation 'io.repro:repro-android-sdk:5.24.0'
  testImplementation 'junit:junit:4.12'
  androidTestImplementation 'com.android.support.test:runner:1.0.2'
  androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
```

**build.gradle.kts (Kotlin DSL)**

```groovy
dependencies {
  implementation("io.repro:repro-android-sdk:5.24.0")
  testImplementation("junit:junit:4.12")
  androidTestImplementation("com.android.support.test:runner:1.0.2")
  androidTestImplementation("com.android.support.test.espresso:espresso-core:3.0.2")
}
```

#### Android Gradle Plugin 8.0 以上を利用する場合の対応

ご利用の Android Gradle Plugin のバージョンにより、アプリのビルド時に以下のようなエラーが発生する場合があります。

```
A problem occurred configuring project ':repro_flutter'.
> Could not create an instance of type com.android.build.api.variant.impl.LibraryVariantBuilderImpl.
> Namespace not specified. Specify a namespace in the module's build file. See https://d.android.com/r/tools/upgrade-assistant/set-namespace for information about setting the namespace.
```

このようなエラーが発生した場合、Flutter の Android プロジェクト直下の `build.gradle` または `build.gradle.kts` ファイル内 `allprojects` ブロックに以下のコードを追記してください。

**build.gradle (Groovy)**

```groovy
subprojects {
    afterEvaluate { project ->
        if (project.hasProperty('android')) {
            project.android {
                if (namespace == null) {
                    namespace project.group
                }
            }
        }
    }
}
```

**build.gradle.kts (Kotlin DSL)**

```groovy
subprojects {
    afterEvaluate {
        if (extensions.findByName("android") != null) {
            extensions.configure<com.android.build.gradle.BaseExtension> {
                if (namespace.isNullOrEmpty()) {
                    namespace = project.group.toString()
                }
            }
        }
    }
}
```

### セットアップ

#### iOS

`AppDelegate` で `Repro` をインポートしたうえで、 `application:didFinishLaunchingWithOptions:` で `Repro#setup` を実行して [セッション](https://docs.repro.io/ja/dev/sdk/session.md) を開始します。

`YOUR_APP_TOKEN` には管理画面の **設定 > プロジェクト設定 > 認証情報** に記載されている **SDK トークン** を設定してください。

```dart
// This section explains the implementation in iOS.
// Please change the language to Objective-C or Swift.
```

```objc
- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  [GeneratedPluginRegistrant registerWithRegistry:self];
  // Override point for customization after application launch.
  [Repro setup:@"YOUR_APP_TOKEN"];
  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
```

```swift
override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
  GeneratedPluginRegistrant.register(with: self)
  // Override point for customization after application launch.
  Repro.setup(token: "YOUR_APP_TOKEN")
  return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
```

```java
// This section explains the implementation in iOS.
// Please change the language to Objective-C or Swift.
```

```kotlin
// This section explains the implementation in iOS.
// Please change the language to Objective-C or Swift.
```

#### Android

`android.app.Application` を継承した独自の `Application` クラスを作成します。
すでにクラスを作成している場合は、独自の `Application` クラスを作成する必要はありません。

```dart
// This section explains the implementation in Android.
// Please change the language to Java or Kotlin.
```

```objc
// This section explains the implementation in Android.
// Please change the language to Java or Kotlin.
```

```swift
// This section explains the implementation in Android.
// Please change the language to Java or Kotlin.
```

```java
package your.package.name;

import android.app.Application;
import io.repro.android.Repro;

public class MainApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
    }
}
```

```kotlin
package your.package.name

import android.app.Application
import io.repro.android.Repro

class MainApplication : Application() {

    override fun onCreate() {
        super.onCreate()
    }
}
```

また `AndroidManifest.xml` の記述を以下のように修正します。

```diff
    <application
-         android:name="${applicationName}"
+         android:name="your.package.name.MainApplication"
          android:label="repro_integration_test"
          android:icon="@mipmap/ic_launcher">
```

独自 `Application` クラスの `onCreate` メソッドで `Repro.setup` を実行して、新しい [セッション](https://docs.repro.io/ja/dev/sdk/session.md) を開始してください。

```dart
// This section explains the implementation in Android.
// Please change the language to Java or Kotlin.
```

```objc
// This section explains the implementation in Android.
// Please change the language to Java or Kotlin.
```

```swift
// This section explains the implementation in Android.
// Please change the language to Java or Kotlin.
```

```java
public void onCreate() {
    super.onCreate();
    Repro.setup(this, "YOUR_APP_TOKEN");
}
```

```kotlin
override fun onCreate() {
    super.onCreate()
    Repro.setup(this, "YOUR_APP_TOKEN")
}
```

`YOUR_APP_TOKEN` には管理画面の **設定 > プロジェクト設定 > 認証情報** に記載されている **SDK トークン** を設定してください。

SDKが収集した情報は定期的にサーバーにアップロードされます。

### イベントをトラックする

意味のある分析や、マーケティング施策を実施するためには、適切なユーザーグループを絞り込むことが重要です。イベントをトラックしてユーザーの行動を記録することにより、管理画面上で目的に応じた適切なユーザーグループを選択することができるようになります。

イベントを用いたユーザーグループ指定の例:

- [キャンペーンの作成画面で、イベントやユーザープロフィールを組み合わせて、配信対象となるユーザーグループを指定する](https://docs.repro.io/ja/dashboard/campaign/target.md)

どういうイベントをとるべきかわからない場合は、まず各画面の表示時にイベントをとってみることをおすすめします。

例:

```objc
@implementation MainViewController

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [Repro track:@"MainViewController" properties:nil];

    ...
}
```

```swift
class MainViewController: UIViewController {

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        Repro.track(event: "MainViewController", properties: [:])

        ...
    }
```

```java
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onResume() {
        super.onResume();
        Repro.track("MainActivity");

        ...
    }
}
```

```kotlin
class MainActivity : AppCompatActivity() {

    override fun onResume() {
        super.onResume()
        Repro.track("MainActivity")

        ...
    }
}
```

```cpp
#include "ReproCpp.h"

...

ReproCpp::track("Initialized");
```

```csharp
Repro.Track ("Initialized");
```

```js-cordova
// Will be written later
```

```js-react-native
class MainScreen extends React.Component {

    componentDidMount() {
        Repro.track("MainScreen", {});
    }

    ...
 }
```

```js-expo
import Repro from 'react-native-repro';

...

Repro.track("MainScreen", {});
```

```dart
import 'package:repro_flutter/repro.dart';

...

await Repro.track("Initialized");
```

### ユーザーIDをセットする

Repro では分析結果はユーザー単位で集計しています。ユーザーIDをセットすることにより、下記のメリットがあります:

- 複数のデバイスを使っているユーザーを同一視できる
- キャンペーンの配信対象の抽出がより精緻になる

詳しくは [こちら](https://docs.repro.io/ja/dev/sdk/user-id.md) をご覧ください。

### プッシュ通知を配信する

Reproでは、管理画面もしくはAPIからプッシュ通知配信をすることができます。プッシュ通知配信をするための実装は [こちら](https://docs.repro.io/ja/dev/sdk/push-notification/index.md) をご覧ください。

### Next...

その他の機能についての詳細は、以下をご覧ください。

- [セッション・ライフサイクル](https://docs.repro.io/ja/dev/sdk/session.md)
- [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md)
- [ユーザーID](https://docs.repro.io/ja/dev/sdk/user-id.md)
- [デバイスID](https://docs.repro.io/ja/dev/sdk/device-id.md)
- [ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md)
- [WebView](https://docs.repro.io/ja/dev/sdk/webview.md)
- [オプトアウト機能](https://docs.repro.io/ja/dev/sdk/optout/index.md)
- [アプリ内メッセージ](https://docs.repro.io/ja/dev/sdk/in-app-message.md)
- [プッシュ通知](https://docs.repro.io/ja/dev/sdk/push-notification/index.md)
- [Adjustで取得したアトリビューションデータをReproにセットする](https://docs.repro.io/ja/dev/sdk/integrate-adjust.md)
- [AppsFlyerで取得したアトリビューションデータをReproにセットする](https://docs.repro.io/ja/dev/sdk/integrate-appsflyer.md)

---

## iOS/Android SDK

* [導入](https://docs.repro.io/ja/dev/sdk/getstarted/index.md)
  * [SDK の導入](https://docs.repro.io/ja/dev/sdk/getstarted/index.md#sdk)
    * [iOS](https://docs.repro.io/ja/dev/sdk/getstarted/ios.md)
    * [Android](https://docs.repro.io/ja/dev/sdk/getstarted/android.md)
    * [Unity](https://docs.repro.io/ja/dev/sdk/getstarted/unity.md)
    * [Cordova](https://docs.repro.io/ja/dev/sdk/getstarted/cordova.md)
    * [Monaca](https://docs.repro.io/ja/dev/sdk/getstarted/monaca.md)
    * [Cocos2d-x](https://docs.repro.io/ja/dev/sdk/getstarted/cocos2d-x.md)
    * [React Native](https://docs.repro.io/ja/dev/sdk/getstarted/react-native.md)
    * [React Native (Expo)](https://docs.repro.io/ja/dev/sdk/getstarted/expo.md)
    * [Flutter](https://docs.repro.io/ja/dev/sdk/getstarted/flutter.md)
* [セッション・ライフサイクル](https://docs.repro.io/ja/dev/sdk/session.md)
  * [iOS/Android](https://docs.repro.io/ja/dev/sdk/session.md#ios-android)
    * [セッションの期間](https://docs.repro.io/ja/dev/sdk/session.md#id2)
    * [セッションの開始](https://docs.repro.io/ja/dev/sdk/session.md#id3)
    * [セッションの終了](https://docs.repro.io/ja/dev/sdk/session.md#stop-session)
* [ユーザーID](https://docs.repro.io/ja/dev/sdk/user-id.md)
  * [ユーザーIDをセットする](https://docs.repro.io/ja/dev/sdk/user-id.md#set-app-user-id)
  * [ユーザーIDを取得する](https://docs.repro.io/ja/dev/sdk/user-id.md#get-app-user-id)
* [デバイスID](https://docs.repro.io/ja/dev/sdk/device-id.md)
  * [デバイスIDを取得](https://docs.repro.io/ja/dev/sdk/device-id.md#get-app-divice-id)
* [ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md)
  * [標準ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md#standard-user-profile)
    * [性別](https://docs.repro.io/ja/dev/sdk/user-profile.md#id3)
    * [Eメールアドレス](https://docs.repro.io/ja/dev/sdk/user-profile.md#e)
    * [都道府県](https://docs.repro.io/ja/dev/sdk/user-profile.md#id4)
    * [生年月日](https://docs.repro.io/ja/dev/sdk/user-profile.md#id5)
    * [年齢](https://docs.repro.io/ja/dev/sdk/user-profile.md#id6)
  * [自動でセットされる標準ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md#id7)
    * [最後に使った日](https://docs.repro.io/ja/dev/sdk/user-profile.md#id8)
    * [ロケール](https://docs.repro.io/ja/dev/sdk/user-profile.md#id9)
    * [ランダムバケットID](https://docs.repro.io/ja/dev/sdk/user-profile.md#id)
    * [タイムゾーン](https://docs.repro.io/ja/dev/sdk/user-profile.md#id10)
  * [カスタムユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md#custom-profile)
    * [文字列](https://docs.repro.io/ja/dev/sdk/user-profile.md#setstringuserprofile)
    * [整数](https://docs.repro.io/ja/dev/sdk/user-profile.md#setintuserprofile)
    * [小数](https://docs.repro.io/ja/dev/sdk/user-profile.md#setdoubleuserprofile)
    * [日付](https://docs.repro.io/ja/dev/sdk/user-profile.md#setdateuserprofile)
  * [条件付きセット操作](https://docs.repro.io/ja/dev/sdk/user-profile.md#user-profile-conditional-set)
    * [文字列（条件付き）](https://docs.repro.io/ja/dev/sdk/user-profile.md#id17)
    * [整数（条件付き）](https://docs.repro.io/ja/dev/sdk/user-profile.md#id18)
    * [小数（条件付き）](https://docs.repro.io/ja/dev/sdk/user-profile.md#id19)
    * [日付（条件付き）](https://docs.repro.io/ja/dev/sdk/user-profile.md#id20)
  * [増減操作](https://docs.repro.io/ja/dev/sdk/user-profile.md#user-profile-increment-and-decrement)
    * [整数の増加](https://docs.repro.io/ja/dev/sdk/user-profile.md#id22)
    * [整数の減少](https://docs.repro.io/ja/dev/sdk/user-profile.md#id23)
    * [小数の増加](https://docs.repro.io/ja/dev/sdk/user-profile.md#id24)
    * [小数の減少](https://docs.repro.io/ja/dev/sdk/user-profile.md#id25)
  * [標準ユーザープロフィールの条件付きセット・増減操作](https://docs.repro.io/ja/dev/sdk/user-profile.md#id26)
    * [年齢（条件付き）](https://docs.repro.io/ja/dev/sdk/user-profile.md#id27)
    * [性別（条件付き）](https://docs.repro.io/ja/dev/sdk/user-profile.md#id28)
    * [Eメールアドレス（条件付き）](https://docs.repro.io/ja/dev/sdk/user-profile.md#id29)
    * [居住都道府県（条件付き）](https://docs.repro.io/ja/dev/sdk/user-profile.md#id30)
    * [生年月日（条件付き）](https://docs.repro.io/ja/dev/sdk/user-profile.md#id31)
    * [年齢の増加](https://docs.repro.io/ja/dev/sdk/user-profile.md#id32)
    * [年齢の減少](https://docs.repro.io/ja/dev/sdk/user-profile.md#id33)
  * [ユーザープロフィールの削除](https://docs.repro.io/ja/dev/sdk/user-profile.md#id34)
    * [カスタムプロフィールの削除](https://docs.repro.io/ja/dev/sdk/user-profile.md#id35)
    * [標準プロフィールの削除](https://docs.repro.io/ja/dev/sdk/user-profile.md#id36)
* [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md)
  * [標準イベント](https://docs.repro.io/ja/dev/sdk/tracking.md#standard-event)
    * [閲覧](https://docs.repro.io/ja/dev/sdk/tracking.md#id3)
    * [検索](https://docs.repro.io/ja/dev/sdk/tracking.md#id4)
    * [カートに追加](https://docs.repro.io/ja/dev/sdk/tracking.md#id5)
    * [ウィッシュリストに追加](https://docs.repro.io/ja/dev/sdk/tracking.md#id6)
    * [支払い開始](https://docs.repro.io/ja/dev/sdk/tracking.md#id7)
    * [支払い情報追加](https://docs.repro.io/ja/dev/sdk/tracking.md#id8)
    * [購入](https://docs.repro.io/ja/dev/sdk/tracking.md#track-purchase)
    * [シェア](https://docs.repro.io/ja/dev/sdk/tracking.md#id10)
    * [リード](https://docs.repro.io/ja/dev/sdk/tracking.md#id11)
    * [ユーザー登録](https://docs.repro.io/ja/dev/sdk/tracking.md#id12)
    * [独自プロパティの追加](https://docs.repro.io/ja/dev/sdk/tracking.md#extra-properties)
  * [カスタムイベント](https://docs.repro.io/ja/dev/sdk/tracking.md#custom-event)
* [プッシュ通知](https://docs.repro.io/ja/dev/sdk/push-notification/index.md)
  * [APNs証明書の設定 (iOS)](https://docs.repro.io/ja/dev/sdk/push-notification/setup-ios.md)
    * [APP IDの作成](https://docs.repro.io/ja/dev/sdk/push-notification/setup-ios.md#app-id)
    * [証明書の作成](https://docs.repro.io/ja/dev/sdk/push-notification/setup-ios.md#create-certificate)
    * [Provisioning Profileの設定](https://docs.repro.io/ja/dev/sdk/push-notification/setup-ios.md#provisioning-profile)
  * [FCMの設定 (Android)](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md)
    * [プロジェクトの作成](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md#id1)
    * [アプリの登録](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md#firebase-register-app)
    * [Firebase Cloud Messaging API（V1）を有効にする](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md#firebase-cloud-messaging-api-v1)
    * [Firebaseの秘密鍵を生成](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md#firebase)
    * [Firebaseの秘密鍵をReproに登録](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md#firebaserepro)
  * [iOS](https://docs.repro.io/ja/dev/sdk/push-notification/ios.md)
    * [プッシュ通知の設定](https://docs.repro.io/ja/dev/sdk/push-notification/ios.md#id1)
    * [バッジを消す処理の実装](https://docs.repro.io/ja/dev/sdk/push-notification/ios.md#clear-badge)
    * [デバイストークンをReproに送信](https://docs.repro.io/ja/dev/sdk/push-notification/ios.md#repro)
    * [オプション：リッチ通知の受信準備](https://docs.repro.io/ja/dev/sdk/push-notification/ios.md#ios-receiving-rich-notification)
    * [オプション：ユニバーサルリンクを使用する](https://docs.repro.io/ja/dev/sdk/push-notification/ios.md#ios-universal-link-guide)
  * [Android](https://docs.repro.io/ja/dev/sdk/push-notification/android.md)
    * [プッシュ通知の設定](https://docs.repro.io/ja/dev/sdk/push-notification/android.md#id1)
    * [Firebase SDKを導入する](https://docs.repro.io/ja/dev/sdk/push-notification/android.md#firebase-sdk)
    * [`AndroidManifest.xml` ファイルを編集する](https://docs.repro.io/ja/dev/sdk/push-notification/android.md#androidmanifest-xml)
    * [Registration IDをReproに送信](https://docs.repro.io/ja/dev/sdk/push-notification/android.md#registration-idrepro)
    * [オプション：プッシュ通知受信時の動作をカスタマイズする](https://docs.repro.io/ja/dev/sdk/push-notification/android.md#customize-receiver)
    * [オプション：アプリリンクを使用する](https://docs.repro.io/ja/dev/sdk/push-notification/android.md#android-app-link-guide)
  * [Unity](https://docs.repro.io/ja/dev/sdk/push-notification/unity.md)
    * [プッシュ通知の設定](https://docs.repro.io/ja/dev/sdk/push-notification/unity.md#id1)
    * [Firebase Unity SDKを導入する](https://docs.repro.io/ja/dev/sdk/push-notification/unity.md#firebase-unity-sdk)
    * [iOSプラットフォーム](https://docs.repro.io/ja/dev/sdk/push-notification/unity.md#ios)
    * [Androidプラットフォーム](https://docs.repro.io/ja/dev/sdk/push-notification/unity.md#android)
    * [オプション：ユニバーサルリンク/アプリリンクを使用する](https://docs.repro.io/ja/dev/sdk/push-notification/unity.md#universal-link-guide-unity)
  * [Cordova](https://docs.repro.io/ja/dev/sdk/push-notification/cordova.md)
    * [プッシュ通知の設定](https://docs.repro.io/ja/dev/sdk/push-notification/cordova.md#id1)
    * [`config.xml` ファイルを編集する](https://docs.repro.io/ja/dev/sdk/push-notification/cordova.md#config-xml)
    * [`google-services.json` ファイルを追加する](https://docs.repro.io/ja/dev/sdk/push-notification/cordova.md#google-services-json)
    * [Google Services Gradle Pluginを導入する](https://docs.repro.io/ja/dev/sdk/push-notification/cordova.md#google-services-gradle-plugin)
    * [オプション：Firebaseの依存バージョンを変更する](https://docs.repro.io/ja/dev/sdk/push-notification/cordova.md#firebase)
    * [デバイストークン、Registration IDをReproに送信](https://docs.repro.io/ja/dev/sdk/push-notification/cordova.md#registration-idrepro)
    * [オプション：ユニバーサルリンク/アプリリンクを使用する](https://docs.repro.io/ja/dev/sdk/push-notification/cordova.md#universal-link-guide-cordova)
  * [Monaca](https://docs.repro.io/ja/dev/sdk/push-notification/monaca.md)
    * [プッシュ通知の設定](https://docs.repro.io/ja/dev/sdk/push-notification/monaca.md#id1)
    * [`config.xml` ファイルを編集する](https://docs.repro.io/ja/dev/sdk/push-notification/monaca.md#config-xml)
    * [`google-services.json` ファイルを追加する](https://docs.repro.io/ja/dev/sdk/push-notification/monaca.md#google-services-json)
    * [Google Services Gradle Pluginを導入する](https://docs.repro.io/ja/dev/sdk/push-notification/monaca.md#google-services-gradle-plugin)
    * [オプション：Firebaseの依存バージョンを変更する](https://docs.repro.io/ja/dev/sdk/push-notification/monaca.md#firebase)
    * [デバイストークン、Registration IDをReproに送信](https://docs.repro.io/ja/dev/sdk/push-notification/monaca.md#registration-idrepro)
    * [オプション：ユニバーサルリンク/アプリリンクを使用する](https://docs.repro.io/ja/dev/sdk/push-notification/monaca.md#id7)
  * [Cocos2d-x](https://docs.repro.io/ja/dev/sdk/push-notification/cocos2d-x.md)
    * [プッシュ通知の設定](https://docs.repro.io/ja/dev/sdk/push-notification/cocos2d-x.md#id1)
    * [Firebase C++ SDKを導入する](https://docs.repro.io/ja/dev/sdk/push-notification/cocos2d-x.md#firebase-c-sdk)
    * [iOSプロジェクトの実装](https://docs.repro.io/ja/dev/sdk/push-notification/cocos2d-x.md#ios)
    * [Androidプロジェクトの実装](https://docs.repro.io/ja/dev/sdk/push-notification/cocos2d-x.md#android)
    * [オプション：ユニバーサルリンク/アプリリンクを使用する](https://docs.repro.io/ja/dev/sdk/push-notification/cocos2d-x.md#universal-link-guide-cocos2d-x)
  * [React Native](https://docs.repro.io/ja/dev/sdk/push-notification/react-native.md)
    * [プッシュ通知の設定 (iOS)](https://docs.repro.io/ja/dev/sdk/push-notification/react-native.md#ios)
    * [プッシュ通知の設定 (Android)](https://docs.repro.io/ja/dev/sdk/push-notification/react-native.md#android)
    * [オプション：ユニバーサルリンク/アプリリンクを使用する](https://docs.repro.io/ja/dev/sdk/push-notification/react-native.md#universal-link-guide-react-native)
  * [React Native (Expo)](https://docs.repro.io/ja/dev/sdk/push-notification/expo.md)
    * [FCMの設定 (Android)](https://docs.repro.io/ja/dev/sdk/push-notification/expo.md#fcm-android)
    * [APNs証明書の設定 (iOS)](https://docs.repro.io/ja/dev/sdk/push-notification/expo.md#apns-ios)
    * [React Native Firebase をインストールする (Android)](https://docs.repro.io/ja/dev/sdk/push-notification/expo.md#react-native-firebase-android)
    * [React Native Firebase の設定 (iOSプロジェクトを含む場合)](https://docs.repro.io/ja/dev/sdk/push-notification/expo.md#react-native-firebase-ios)
    * [チャネルの設定を追加する (Android)](https://docs.repro.io/ja/dev/sdk/push-notification/expo.md#android)
    * [google-services.json ファイルを配置する (Android)](https://docs.repro.io/ja/dev/sdk/push-notification/expo.md#google-services-json-android)
    * [Expo Notifications をインストールする (iOS/Android)](https://docs.repro.io/ja/dev/sdk/push-notification/expo.md#expo-notifications-ios-android)
    * [Entitlementsの設定を行う (iOS)](https://docs.repro.io/ja/dev/sdk/push-notification/expo.md#entitlements-ios)
    * [プッシュトークンをReproに送信する処理を実装する (iOS/Android)](https://docs.repro.io/ja/dev/sdk/push-notification/expo.md#repro-ios-android)
    * [アプリケーションのネイティブコードを生成する (iOS/Android)](https://docs.repro.io/ja/dev/sdk/push-notification/expo.md#ios-android)
  * [Flutter](https://docs.repro.io/ja/dev/sdk/push-notification/flutter.md)
    * [プッシュ通知の設定(iOS)](https://docs.repro.io/ja/dev/sdk/push-notification/flutter.md#ios)
    * [プッシュ通知の設定(Android)](https://docs.repro.io/ja/dev/sdk/push-notification/flutter.md#android)
    * [オプション：ユニバーサルリンク/アプリリンクを使用する](https://docs.repro.io/ja/dev/sdk/push-notification/flutter.md#universal-link-guide-flutter)
* [ニュースフィード](https://docs.repro.io/ja/dev/sdk/newsfeed.md)
  * [ニュースフィードの仕様について](https://docs.repro.io/ja/dev/sdk/newsfeed.md#id2)
    * [一度に取得可能なキャンペーン数](https://docs.repro.io/ja/dev/sdk/newsfeed.md#id3)
    * [遡ることの出来るキャンペーン期間](https://docs.repro.io/ja/dev/sdk/newsfeed.md#id4)
  * [ニュースフィードインターフェース](https://docs.repro.io/ja/dev/sdk/newsfeed.md#id5)
    * [データ形式](https://docs.repro.io/ja/dev/sdk/newsfeed.md#id6)
    * [ニュースフィードを取得する](https://docs.repro.io/ja/dev/sdk/newsfeed.md#id7)
    * [ニュースフィードを更新する](https://docs.repro.io/ja/dev/sdk/newsfeed.md#id11)
* [アプリ内メッセージ](https://docs.repro.io/ja/dev/sdk/in-app-message.md)
  * [実装の追加／変更が必要なケース](https://docs.repro.io/ja/dev/sdk/in-app-message.md#id2)
    * [アプリ起動時にスプラッシュスクリーンを表示したり画面遷移をしている場合](https://docs.repro.io/ja/dev/sdk/in-app-message.md#id3)
    * [アプリ起動直後に実行されるイベント（「アプリ起動」以外）をアプリ内メッセージの表示トリガーに利用する場合](https://docs.repro.io/ja/dev/sdk/in-app-message.md#id5)
    * [画面遷移前後に実行されるイベントをアプリ内メッセージの表示トリガーに利用する場合](https://docs.repro.io/ja/dev/sdk/in-app-message.md#in-app-message-show-timing)
    * [カスタムURL Schemeを使用する場合](https://docs.repro.io/ja/dev/sdk/in-app-message.md#url-scheme)
    * [ユニバーサルリンク/アプリリンクを使用する場合](https://docs.repro.io/ja/dev/sdk/in-app-message.md#id7)
    * [App-Bound Domains を有効にしている場合（iOSのみ）](https://docs.repro.io/ja/dev/sdk/in-app-message.md#app-bound-domains-ios)
* [シルバーエッグレコメンドメッセージ](https://docs.repro.io/ja/dev/sdk/silver-egg-recommend-in-app-message.md)
  * [はじめに](https://docs.repro.io/ja/dev/sdk/silver-egg-recommend-in-app-message.md#id2)
  * [設定例](https://docs.repro.io/ja/dev/sdk/silver-egg-recommend-in-app-message.md#id3)
* [アプリ内パラメーター](https://docs.repro.io/ja/dev/sdk/remote-config.md)
  * [Remote Config インターフェース](https://docs.repro.io/ja/dev/sdk/remote-config.md#remote-config)
    * [ローカルのデフォルト値を設定する](https://docs.repro.io/ja/dev/sdk/remote-config.md#id2)
  * [Remote Config の値にアクセスする](https://docs.repro.io/ja/dev/sdk/remote-config.md#id3)
    * [特定の値にアクセスする](https://docs.repro.io/ja/dev/sdk/remote-config.md#id4)
    * [Remote Config全体](https://docs.repro.io/ja/dev/sdk/remote-config.md#id5)
    * [プリフィックスを指定してアクセスする](https://docs.repro.io/ja/dev/sdk/remote-config.md#id6)
    * [値をリセットする](https://docs.repro.io/ja/dev/sdk/remote-config.md#id7)
    * [Fetch と Activate](https://docs.repro.io/ja/dev/sdk/remote-config.md#fetch-activate)
* [WebView](https://docs.repro.io/ja/dev/sdk/webview.md)
  * [WebViewでReproの利用を有効にする](https://docs.repro.io/ja/dev/sdk/webview.md#webviewrepro)
    * [iOS](https://docs.repro.io/ja/dev/sdk/webview.md#ios)
    * [Android](https://docs.repro.io/ja/dev/sdk/webview.md#android)
    * [React Native](https://docs.repro.io/ja/dev/sdk/webview.md#react-native)
    * [Flutter](https://docs.repro.io/ja/dev/sdk/webview.md#flutter)
  * [Webページにトラッキングコードを追加する](https://docs.repro.io/ja/dev/sdk/webview.md#web)
    * [JavaScriptライブラリrepro.jsを読み込む](https://docs.repro.io/ja/dev/sdk/webview.md#javascriptrepro-js)
    * [トラッキングコードを実装する](https://docs.repro.io/ja/dev/sdk/webview.md#id1)
* [オプトアウト機能](https://docs.repro.io/ja/dev/sdk/optout/index.md)
  * [オプトイン/オプトアウトの指定](https://docs.repro.io/ja/dev/sdk/optout/index.md#optin-api)
  * [初期状態の指定](https://docs.repro.io/ja/dev/sdk/optout/index.md#id3)
    * [iOS](https://docs.repro.io/ja/dev/sdk/optout/ios.md)
    * [Android](https://docs.repro.io/ja/dev/sdk/optout/android.md)
    * [Unity](https://docs.repro.io/ja/dev/sdk/optout/unity.md)
    * [Cordova](https://docs.repro.io/ja/dev/sdk/optout/cordova.md)
    * [Monaca](https://docs.repro.io/ja/dev/sdk/optout/monaca.md)
    * [Cocos2d-x](https://docs.repro.io/ja/dev/sdk/optout/cocos2d-x.md)
    * [React Native](https://docs.repro.io/ja/dev/sdk/optout/react-native.md)
    * [Flutter](https://docs.repro.io/ja/dev/sdk/optout/flutter.md)
* [広告ID取得設定](https://docs.repro.io/ja/dev/sdk/ad-id.md)
  * [Android](https://docs.repro.io/ja/dev/sdk/ad-id.md#android)
    * [広告IDの取得を有効にする](https://docs.repro.io/ja/dev/sdk/ad-id.md#id1)
    * [許可の追加](https://docs.repro.io/ja/dev/sdk/ad-id.md#id2)
    * [依存ライブラリの追加](https://docs.repro.io/ja/dev/sdk/ad-id.md#id3)
  * [iOS](https://docs.repro.io/ja/dev/sdk/ad-id.md#ios)
* [QRコードを用いてオーディエンスにユーザーを登録する](https://docs.repro.io/ja/dev/sdk/qr-code.md)
  * [Android](https://docs.repro.io/ja/dev/sdk/qr-code.md#android)
  * [iOS](https://docs.repro.io/ja/dev/sdk/qr-code.md#ios)
* [Adjustで取得したアトリビューションデータをReproにセットする](https://docs.repro.io/ja/dev/sdk/integrate-adjust.md)
  * [ユーザープロフィールにセットする](https://docs.repro.io/ja/dev/sdk/integrate-adjust.md#id1)
  * [イベントプロパティにセットする](https://docs.repro.io/ja/dev/sdk/integrate-adjust.md#id2)
* [AppsFlyerで取得したアトリビューションデータをReproにセットする](https://docs.repro.io/ja/dev/sdk/integrate-appsflyer.md)
  * [ユーザープロフィールにセットする](https://docs.repro.io/ja/dev/sdk/integrate-appsflyer.md#id1)
  * [イベントプロパティにセットする](https://docs.repro.io/ja/dev/sdk/integrate-appsflyer.md#id2)
* [ReproへのLINEユーザーIDの登録 (iOS/Android SDK)](https://docs.repro.io/ja/dev/sdk/line-integration.md)
  * [LINEユーザーIDの登録](https://docs.repro.io/ja/dev/sdk/line-integration.md#lineid)
  * [LINEユーザーIDの登録解除](https://docs.repro.io/ja/dev/sdk/line-integration.md#id1)
  * [Notes](https://docs.repro.io/ja/dev/sdk/line-integration.md#notes)
* [ログレベル](https://docs.repro.io/ja/dev/sdk/log.md)
  * [ログレベルを変更する](https://docs.repro.io/ja/dev/sdk/log.md#id2)
* [検証方法](https://docs.repro.io/ja/dev/sdk/tests/index.md)
  * [セットアップ](https://docs.repro.io/ja/dev/sdk/tests/setup.md)
  * [ユーザーID](https://docs.repro.io/ja/dev/sdk/tests/user_id.md)
    * [1. IDEのログを確認](https://docs.repro.io/ja/dev/sdk/tests/user_id.md#ide)
    * [2. オーディエンスに追加出来るかを確認](https://docs.repro.io/ja/dev/sdk/tests/user_id.md#id1)
  * [ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/tests/user_profile.md)
    * [1. IDEのログを確認](https://docs.repro.io/ja/dev/sdk/tests/user_profile.md#ide)
    * [2. 管理画面のユーザープロフィール設定から確認](https://docs.repro.io/ja/dev/sdk/tests/user_profile.md#id2)
    * [3. オーディエンス機能を利用して確認](https://docs.repro.io/ja/dev/sdk/tests/user_profile.md#id3)
  * [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tests/events.md)
  * [アプリ内メッセージ](https://docs.repro.io/ja/dev/sdk/tests/inapp.md)
  * [プッシュ通知](https://docs.repro.io/ja/dev/sdk/tests/push.md)

---

## 導入

### SDK の導入

お使いのプラットフォームに従い、SDKの導入を進めてください。

* [iOS](https://docs.repro.io/ja/dev/sdk/getstarted/ios.md)
* [Android](https://docs.repro.io/ja/dev/sdk/getstarted/android.md)
* [Unity](https://docs.repro.io/ja/dev/sdk/getstarted/unity.md)
* [Cordova](https://docs.repro.io/ja/dev/sdk/getstarted/cordova.md)
* [Monaca](https://docs.repro.io/ja/dev/sdk/getstarted/monaca.md)
* [Cocos2d-x](https://docs.repro.io/ja/dev/sdk/getstarted/cocos2d-x.md)
* [React Native](https://docs.repro.io/ja/dev/sdk/getstarted/react-native.md)
* [React Native (Expo)](https://docs.repro.io/ja/dev/sdk/getstarted/expo.md)
* [Flutter](https://docs.repro.io/ja/dev/sdk/getstarted/flutter.md)

---

dart

## プッシュ通知 (Flutter)

### プッシュ通知の設定(iOS)

1. [APNs証明書の設定 (iOS)](https://docs.repro.io/ja/dev/sdk/push-notification/setup-ios.md) を参照し、設定してください。
2. [プッシュ通知（iOS）](https://docs.repro.io/ja/dev/sdk/push-notification/ios.md) を参照し、デバイストークンを Repro に送信するための実装を行ってください。

### プッシュ通知の設定(Android)

1. [Flutter アプリに Firebase を追加する](https://firebase.google.com/docs/flutter/setup?hl=ja) および [FlutterFire Overview | FlutterFire](https://firebase.flutter.dev/docs/overview/) を参照し、FlutterFireの導入および設定を行ってください。(プッシュ通知の利用には `firebase_core` および `firebase_messaging` の導入が必要です。)
2. [FCMの設定 (Android)](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md) と [プッシュ通知（Android）](https://docs.repro.io/ja/dev/sdk/push-notification/android.md) を参照し、設定してください。(サンプルコードの表示言語をDartに切り替えてご確認ください。)
   * [プッシュ通知（Android）](https://docs.repro.io/ja/dev/sdk/push-notification/android.md) の `build.gradle` への `implementation` の追記は不要です。

##### NOTE
- 弊社では `firebase_core 3.12.1` および `firebase_messaging 15.2.4` を導入した状態で動作を確認しております。
- プッシュ通知受信時の動作をカスタマイズする方法については、 [オプション：プッシュ通知受信時の動作をカスタマイズする](android.html#customize-receiver) 内でDartにて実装を行う方法を掲載しております。
  ページ内のサンプルコードの言語を切り替えてご確認ください。(`FirebaseMessagingService` 継承クラスの実装は不要ですが、同様の実装をDartにて行う必要があります。)
- プッシュ通知の設定方法については、Flutter Package 付属のサンプルアプリケーションおよび以下のサイトに記載の解説もあわせて参考にしてください。
  - [https://pub.dev/packages/repro_flutter#how-to-run-the-example-app](https://pub.dev/packages/repro_flutter#how-to-run-the-example-app)



### オプション：ユニバーサルリンク/アプリリンクを使用する



端末に表示されたプッシュ通知およびアプリ内メッセージに設定されたリンクをタップした際に実行されるURLには、ユニバーサルリンク（またはアプリリンクと呼ばれる）を指定することが可能です。
（簡単のため、以下ではこれらをユニバーサルリンクと呼びます）

アプリにてユニバーサルリンクの実行時の処理を追加するには、以下の通り実装を行う必要があります。
（ここで設定された動作は、プッシュ通知およびアプリ内メッセージ対し有効となります。）

#### ユニバーサルリンクのURLパターンを登録する

ユニバーサルリンクを利用するためには、まずユニバーサルリンクのURLのパターン（正規表現）を指定する必要があります。

##### NOTE
パターン（正規表現）に合致すると、プッシュ通知の開封時や、アプリ内メッセージの遷移先に設定されたURLに対して、後述のコールバック処理をキックします。

また、アプリ内メッセージでHTMLコンテンツを表示するとき、そのコンテンツ内で発生したリクエストに対してもユニバーサルリンクの判定が行われます。

この指定は、iOSの場合は `AppDelegate` または `.plist` ファイル、Androidの場合は `Application` 継承クラス または `AndroidManifest.xml` ファイルのどちらか一方に記述することで行うことができます。

```objc
// AppDelegate.m

#import <Repro/Repro.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [Repro addOpenUrlFilterRegEx:@"https://example\\.com/page/"];
    [Repro addOpenUrlFilterRegEx:@"your-domain\\.com/.+\?universal=true"];
    ...
}


// .plist file
/*
<dict>
    <key>RPROpenUrlFilterRegExList</key>
    <array>
        <string>https://example\.com/page/</string>
        <string>your-domain\.com/.+\?universal=true</string>
    </array>
    ...
</dict>
*/
```

```java
// MyApplication.java

import io.repro.android.Repro;

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        Repro.addOpenUrlFilterRegEx("https://example\\.com/page/");
        Repro.addOpenUrlFilterRegEx("your-domain\\.com/.+\\?universal=true");
        ...
    }
...
}


// AndroidManifest.xml
// To specify multiple URL patterns, enter them separated by commas.
<application>
    ...
    <meta-data
        android:name="io.repro.android.OpenUrlFilterRegExList"
        android:value="https://example\\.com/page/;your-domain\\.com/.+\\?universal=true">
    </meta-data>
</application>
```

```kotlin
// MyApplication.kt

import io.repro.android.Repro

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        Repro.addOpenUrlFilterRegEx("https://example\\.com/page/")
        Repro.addOpenUrlFilterRegEx("your-domain\\.com/.+\\?universal=true")
        ...
    }
    ...
}


// AndroidManifest.xml
// To specify multiple URL patterns, enter them separated by commas.
<application>
    ...
    <meta-data
        android:name="io.repro.android.OpenUrlFilterRegExList"
        android:value="https://example\\.com/page/;your-domain\\.com/.+\\?universal=true">
    </meta-data>
</application>
```

```swift
// AppDelegate.swift

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
{
    Repro.add(openUrlFilterRegEx: "https://example\\.com/page/")
    Repro.add(openUrlFilterRegEx: "your-domain\\.com/.+\\?universal=true")
    ...
}

// .plist file
/*
<dict>
    <key>RPROpenUrlFilterRegExList</key>
    <array>
        <string>https://example\.com/page/</string>
        <string>your-domain\.com/.+\?universal=true</string>
    </array>
    ...
</dict>
*/
```

```dart
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

```csharp
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

```cpp
// YourAppNameScene.cpp

bool YourAppName::init() {
    ReproCpp::addOpenUrlFilterRegEx("https://example\\.com/page/");
    ReproCpp::addOpenUrlFilterRegEx("your-domain\\.com/.+\\?universal=true");
    ...
}
```

```js-cordova
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

```js-react-native
Please follow native iOS and Android instructions in order to add the filters
to the plist/AndroidManifest files or the main AppDelegate/Application classes.
```

##### WARNING
ユニバーサルリンクとして設定するURLパターンは、可能な限り **ドメインとパスまで含めて具体的に指定** し、 **全て小文字で指定** してください。

もし、 https のようにスキームのみを指定した場合、アプリ内メッセージで表示された画面内で実行されたスクリプトなどによるリクエストもユニバーサルリンクと誤って判定され、意図しないタイミングでコールバック処理が実行される可能性があります。

また、URLパターンのスキーム/ドメイン部分に大文字を使用した場合、HTMLアプリ内メッセージで表示したボタンからユニバーサルリンクを使って遷移させようとするときに、スキーム/ドメイン部分が自動的に小文字に変換されて処理されます。パターン（正規表現）に一致せず、意図したタイミングでコールバック処理が実行されない可能性があります。

#### ユニバーサルリンク実行時の処理を登録する

次に、ユニバーサルリンクが実行された際に動作するコールバック処理を実装します。
処理内には、例えばURLのパターンに応じて画面遷移を行う動作などを記述します。

```objc
#import <Repro/Repro.h>

...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [Repro setOpenUrlCallback:^(NSURL *url) {
        if ([url.host isEqualToString:@"example.com"]) {
            // In case of your universal link perform navigation, present content, ...
            handleUniversalLink(url);
        }
    }];

    ...
    [Repro setup:@"YOUR_APP_TOKEN"];
    ...
}
```

```swift
// Set a callback that is executed everytime an URL is about to be opened
Repro.setOpenUrlCallback { url in
    if url.host == "example.com" {
        // In case of your universal link perform navigation, present content, ...
        handleUniversalLink(url)
    }
}
...
Repro.setup(token: "YOUR_APP_TOKEN")
...
```

```java
import io.repro.android.Repro;

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        // In order to execute a callback when a push notification is tapped,
        // the callback must be set in Application, not Activity.
        Repro.setOpenUrlCallback(new Repro.OpenUrlCallback() {
            // ** This callback method is executed in the main thread **
            @Override
            public void onOpened(Uri uri) {
                if ("example.com".equals(uri.getHost())) {
                    // In case of your universal link perform navigation, present content, ...
                }
            }
        });

        ...
        Repro.setup(this, YOUR_APP_TOKEN);
        ...
    }
    ...
}
```

```kotlin
import io.repro.android.Repro

class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        // In order to execute a callback when a push notification is tapped,
        // the callback must be set in Application, not Activity.
        Repro.setOpenUrlCallback { uri ->
            // ** This callback method is executed in the main thread **
            if (uri.host == "example.com") {
                // In case of your universal link perform navigation, present content, ...
            }
        }

        ...
        Repro.setup(this, "YOUR_APP_TOKEN")
        ...
    }
    ...
}
```

```dart
Repro.setOpenUrlCallback((uri) { // uri is of type Uri
   debugPrint("Universal Link Callback Handler received: " + uri.toString());
});
```

```csharp
// Somewhere before Repro.Setup(...)
Repro.SetOpenUrlCallback(uri => // uri is of type Uri
{
    Debug.Log("Universal Link Callback Handler received: " + uri.ToString());
});
```

```cpp
bool YourAppName::init() {
    ReproCpp::addOpenUrlFilterRegEx(...);

    ReproCpp::setOpenUrlCallback([](const char *url) {
        if (strcmp(url, "example.com") == 0) {
            // In case of your universal link perform navigation, present content, ...
        }
    });

    ReproCpp::setup("YOUR_APP_TOKEN")
    ...
}
```

```js-cordova
Repro.setOpenUrlCallback(function(url) { // url is of type String
    alert('Universal Link Callback Handler received: ' + url);
    if (url.includes("http://example.org")) {
        // In case of your universal link perform navigation, present content, ...
    }
});
```

```js-react-native
Repro.setOpenUrlCallback( (url) => {  // url is of type String
    console.log('Universal Link Callback Handler received: ' + url);
    if (url.includes("http://example.org")) {
        // In case of your universal link perform navigation, present content, ...
    }
});
```

---

## シルバーエッグレコメンドメッセージ

アプリ内メッセージでシルバーエッグレコメンドメッセージを表示するために、アプリ内に追加の実装が必要になります。
このページでは追加の実装について記載します。

##### WARNING
本機能の利用には、以下を全て満たしている必要があります。

- シルバーエッグ・テクノロジー社との契約があり、アイジェントレコメンダーシステムを利用できる状態である
- 弊社へシルバーエッグレコメンドメッセージの利用申請済みである
- Repro iOS SDK 5.3.0 以上、Repro Android SDK 5.2.0以上を利用している

### はじめに

シルバーエッグレコメンドメッセージ表示のため、以下の2つの項目を追加で実装する必要があります。

**(必須)Cookie**
: - シルバーエッグ上でのユーザーIDに相当する値です。アプリ本体で取得しているレコメンデーションの cookie と必ず一緒になるよう設定する必須パラメータです。

**(任意)ProdKey**
: - 指定した `ProdKey` を元に、シルバーエッグレコメンドメッセージを表示します。メッセージ表示トリガー のイベントのイベントプロパティとして設定する任意パラメータです。

### 設定例

1. Reproの初期化(setup)前にシルバーエッグ・テクノロジー社のユーザーID(cookie)の設定とシルバーエッグ・テクノロジー社に登録してある商品ID(prod)のキー名を設定します。

```objc
// Register your user ID (cookie) that you have registered with Silver Egg Technology to ReproSDK.
[Repro setSilverEggCookie:@"silver egg's cookie_id"];
// Register the key name of the event property in which the product ID (prod) registered in Silver Egg Technology is embedded to ReproSDK.
[Repro setSilverEggProdKey:@"product_id"];
// Setup Repro
[Repro setup:@"YOUR_APP_TOKEN"];
```

```swift
// Register your user ID (cookie) that you have registered with Silver Egg Technology to ReproSDK.
Repro.setSilverEggCookie(user_id: "silver egg's cookie_id")
// Register the key name of the event property in which the product ID (prod) registered in Silver Egg Technology is embedded to ReproSDK.
Repro.setSilverEggProdKey(key: "product_id")
// Setup Repro
Repro.setup(token: "YOUR_APP_TOKEN")
```

```java
// Register your user ID (cookie) that you have registered with Silver Egg Technology to ReproSDK.
Repro.setSilverEggCookie("silver egg's cookie_id");
// Register the key name of the event property in which the product ID (prod) registered in Silver Egg Technology is embedded to ReproSDK.
Repro.setSilverEggProdKey("product_id");
// Setup Repro
Repro.setup(this, "YOUR_APP_TOKEN");
```

```cpp
// Register your user ID (cookie) that you have registered with Silver Egg Technology to ReproSDK.
ReproCpp::setSilverEggCookie("silver egg's cookie_id");
// Register the key name of the event property in which the product ID (prod) registered in Silver Egg Technology is embedded to ReproSDK.
ReproCpp::setSilverEggProdKey("product_id");
// Setup Repro
ReproCpp::setup("YOUR_APP_TOKEN");
```

```csharp
// Register your user ID (cookie) that you have registered with Silver Egg Technology to ReproSDK.
Repro.SetSilverEggCookie("silver egg's cookie_id");
// Register the key name of the event property in which the product ID (prod) registered in Silver Egg Technology is embedded to ReproSDK.
Repro.SetSilverEggProdKey("product_id");
// Setup Repro
Repro.Setup("YOUR_APP_TOKEN");
```

```js-cordova
// Register your user ID (cookie) that you have registered with Silver Egg Technology to ReproSDK.
Repro.setSilverEggCookie("silver egg's cookie_id");
// Register the key name of the event property in which the product ID (prod) registered in Silver Egg Technology is embedded to ReproSDK.
Repro.setSilverEggProdKey("product_id");
// Setup Repro
Repro.setup("YOUR_APP_TOKEN");
```

```js-react-native
// Register your user ID (cookie) that you have registered with Silver Egg Technology to ReproSDK.
Repro.setSilverEggCookie("silver egg's cookie_id");
// Register the key name of the event property in which the product ID (prod) registered in Silver Egg Technology is embedded to ReproSDK.
Repro.setSilverEggProdKey("product_id");
...
// Setup Repro
// Write 'Repro.setup' in a class that inherits from Application or AppDelegate.
```

```dart
// Register your user ID (cookie) that you have registered with Silver Egg Technology to ReproSDK.
await Repro.setSilverEggCookie("silver egg's cookie_id");
// Register the key name of the event property in which the product ID (prod) registered in Silver Egg Technology is embedded to ReproSDK.
await Repro.setSilverEggProdKey("product_id");
...
// Setup Repro
// Write 'Repro.setup' in a class that inherits from Application or AppDelegate.
```

1. メッセージ表示イベントトリガーにプロパティとして上記で設定した `ProdKey` を指定して、メッセージを表示します。

```objc
[Repro track:@"addCart" properties:@{
    @"product_id": @"abc123"
}];
```

```swift
Repro.track(event: "addCart", properties:[
    "product_id": "abc123"
])
```

```java
Repro.track("addCart", new HashMap<String, Object>() {{
  put("product_id", "abc123");
}});
```

```cpp
ReproCpp::trackWithProperties("addCart", R"({ "product_id": "abc123" })"); /* Raw string literals, same with {\"product_id\": \"3\"} */
```

```csharp
Repro.TrackWithProperties ("addCart", "{\"product_id\": \"abc123\"}");
```

```js-cordova
Repro.trackWithProperties("addCart", "{\"product_id\": \"abc123\"}");
```

```js-react-native
Repro.track("addCart", { product_id: "abc123" });
```

```js-webview
repro.track("addCart", { product_id: "abc123" });
```

```dart
await Repro.track("addCart", { "product_id": "abc123" });
```

---

## ReproへのLINEユーザーIDの登録 (iOS/Android SDK)

Reproでは、LINEのユーザーIDを登録することで、LINE経由でユーザーにメッセージを送信することができます。

##### WARNING
- LINEユーザーIDのみで登録することはできません。
- LINEユーザーIDは、LINEで登録されているユーザーの表示名や、[LINEでの友だち検索に利用するLINE ID](https://guide.line.me/ja/account-and-settings/account-and-profile/set-line-id.html) とは異なります。
- LINEユーザーIDを登録する前に、事前に [LINEチャネルを作成](https://docs.repro.io/ja/dashboard/setting/line-channel-setting.md) してください。
- LINEユーザーIDを登録する前に、必ず `setUserID()` を使用してユーザーの識別子を設定してください。ユーザーIDが設定されていない状態では、LINEユーザーIDの登録は失敗します。

### LINEユーザーIDの登録

LINEのユーザーIDとチャネルIDをReproに登録するには、 `linkLineID` メソッドを使用します。LINE_USER_IDにはUから始まる33文字のLINEユーザーIDを、LINE_CHANNEL_IDには [LINEチャネル設定](https://docs.repro.io/ja/dashboard/setting/line-channel-setting.md) で作成したチャネルIDを設定してください。

```objc
// Set user ID first
[Repro setUserID:@"user123"];

// Link LINE User ID
[Repro linkLineID:@"LINE_USER_ID" lineChannelID:@"LINE_CHANNEL_ID"];
```

```swift
// Set user ID first
Repro.setUserID("user123")

// Link LINE User ID
Repro.linkLineID(lineUserID: "LINE_USER_ID", lineChannelID: "LINE_CHANNEL_ID")
```

```java
// Set user ID first
Repro.setUserID("user123");

// Link LINE User ID
Repro.linkLineID("LINE_USER_ID", "LINE_CHANNEL_ID");
```

```kotlin
// Set user ID first
Repro.setUserID("user123")

// Link LINE User ID
Repro.linkLineID("LINE_USER_ID", "LINE_CHANNEL_ID")
```

```cpp
// Set user ID first
ReproCpp::setUserID("user123");

// Link LINE User ID
ReproCpp::linkLineID("LINE_USER_ID", "LINE_CHANNEL_ID");
```

```csharp
// Set user ID first
Repro.SetUserID("user123");

// Link LINE User ID
Repro.LinkLineID("LINE_USER_ID", "LINE_CHANNEL_ID");
```

```js-cordova
// Set user ID first
Repro.setUserID("user123");

// Link LINE User ID
Repro.linkLineID("LINE_USER_ID", "LINE_CHANNEL_ID");
```

```js-react-native
// Set user ID first
Repro.setUserID("user123");

// Link LINE User ID
Repro.linkLineID("LINE_USER_ID", "LINE_CHANNEL_ID");
```

```dart
// Set user ID first
await Repro.setUserID("user123");

// Link LINE User ID
await Repro.linkLineID("LINE_USER_ID", "LINE_CHANNEL_ID");
```

### LINEユーザーIDの登録解除

LINEユーザーIDの登録を解除するには、 `unlinkLineID` メソッドを使用します。LINE_USER_IDにはUから始まる33文字のLINEユーザーIDを、LINE_CHANNEL_IDには [LINEチャネル設定](https://docs.repro.io/ja/dashboard/setting/line-channel-setting.md) で作成したチャネルIDを設定してください。

```objc
[Repro unlinkLineID:@"LINE_USER_ID" lineChannelID:@"LINE_CHANNEL_ID"];
```

```swift
Repro.unlinkLineID(lineUserID: "LINE_USER_ID", lineChannelID: "LINE_CHANNEL_ID")
```

```java
Repro.unlinkLineID("LINE_USER_ID", "LINE_CHANNEL_ID");
```

```kotlin
Repro.unlinkLineID("LINE_USER_ID", "LINE_CHANNEL_ID")
```

```cpp
ReproCpp::unlinkLineID("LINE_USER_ID", "LINE_CHANNEL_ID");
```

```csharp
Repro.UnlinkLineID("LINE_USER_ID", "LINE_CHANNEL_ID");
```

```js-cordova
Repro.unlinkLineID("LINE_USER_ID", "LINE_CHANNEL_ID");
```

```js-react-native
Repro.unlinkLineID("LINE_USER_ID", "LINE_CHANNEL_ID");
```

```dart
await Repro.unlinkLineID("LINE_USER_ID", "LINE_CHANNEL_ID");
```

### Notes

- LINEユーザーIDを登録する前に、必ず `setUserID()` でユーザーIDを設定してください。
- LINEユーザーIDとチャネルIDは空文字列やnullを指定できません。
- 登録に失敗した場合は、ユーザーIDが設定されているか確認してください。

---

## LINEチャネル設定

LINEチャネル設定では、 [LINEメッセージ](https://docs.repro.io/ja/dashboard/campaign/line-message.md) の配信に必要となるLINEチャネルの新規作成や編集、削除をすることができます。

### LINEチャネルの新規作成

設定 > LINE設定 > LINEチャネル設定にアクセス



新規作成をクリック



チャネル名、チャネルID、チャネルシークレット、チャネルアクセストークンをそれぞれLINE Developersのチャネル基本設定/Messaging API設定から取得し保存します。



LINEチャネルが保存されます。複数のチャネルをお持ちの場合は新規作成の手順を繰り返します。



### LINEチャネルの編集

チャネルの設定を間違えた場合、⋮  > 編集をクリックし編集できます



### LINEチャネルの削除

不要になったチャネルは、まず ⋮  > 削除をクリックします。確認ダイアログで更に「削除」をクリックすると削除されます。



##### WARNING
- 削除したLINEチャネルを元に戻すことはできません。

---

## LINEメッセージ(β)



ユーザープロフィールやイベントを組み合わせた柔軟なセグメント配信を実現します。
また、ユーザーの行動をトリガーにして最適なタイミングで配信を実施でき、エンゲージメントの高い施策を実現できます。

### LINEメッセージの配信に必要な手順

#### 配信までの流れ

1. [LINEチャネル設定](https://docs.repro.io/ja/dashboard/setting/line-channel-setting.md) から、LINEチャネルを新規作成し、初期設定を完了させます。
2. [ReproへのLINEユーザーIDの登録](https://docs.repro.io/ja/dashboard/setting/line-user-import.md) を参考にLINE配信用ユーザー情報をReproに登録します。
3. Reproの管理画面でLINEメッセージを作成し、配信します。

### LINEメッセージの新規作成

#### LINEメッセージの作成画面に遷移

管理画面にログインし、左メニューの「マーケティング」->「LINE」をクリックし、LINE一覧画面に遷移します。



一覧ページの表示後、右上の「新規作成」ボタンをクリックし、LINEの作成画面に遷移します。



#### キャンペーン情報を入力


- **キャンペーン名**
  LINEのキャンペーン名を記入します
- **キャンペーンのゴール**
  ゴールとなるイベントを選択します
- **キャンペーンの狙いと実施後の結果**
  キャンペーンの狙いと結果を記入します。管理者向けのメモとして利用できます

#### 配信対象設定を入力

キャンペーンの配信対象を指定します。フィルターを利用し、配信対象となるユーザを指定できます。



##### WARNING
- 対象ユーザーの集計にはLINEのユーザーIDを登録していないユーザーも含まれます。

#### 配信元チャネルを指定する

配信元チャネルを指定します。



#### 配信設定を入力

配信設定として、配信時刻や定期配信・即時配信の設定を行います。



##### イベントの実行をトリガーに配信


* トリガー条件を入力します。LINEメッセージを配信する起点となるイベントやプロパティを指定することができます。
  * 最大5つまでのイベントをOR条件で指定できます。
* 指定した起点イベントの実行後すぐに配信するか、一定時間経過後に配信するかを選択することができます。
  * ただし、すぐに配信する設定を行った場合も、サーバーの混雑状況により配信まで数分〜数十分かかる場合があります。
  * 経過時間は最短15分後から最大7日後まで指定できます。
* 配信期間を設定します。
  * キャンペーンの保存後、配信期間は変更できません。変更する場合は該当のキャンペーンを複製してください。
* 配信時間帯を設定します。夜中や早朝などの意図しない時間帯の配信を防ぐために、配信が可能な時間を設定することができます。
  * 設定した配信時間帯以外にトリガー条件のイベントが実行された場合、次の配信時間帯になった時点でLINEメッセージが配信されます。
  * 次の配信時間帯を待っている間にキャンペーンの配信期間を過ぎてしまった場合にはLINEメッセージは配信されません。
  * キャンペーンの保存後、配信時間帯は変更できません。変更する場合は該当のキャンペーンを複製してください。
* 意図しないユーザーへの配信を止めるために、配信をキャンセルするイベントを指定できます。
  * 配信直前やトリガー発火直後にキャンセルするイベントが発生した場合など、配信をキャンセルするイベントの実行タイミングによっては、そのまま配信されてしまう可能性があります。
* LINE配信が1日に何度も配信されることを防ぐため、配信頻度を設定できます。
  * 1日に何度も実行される可能性があるイベントをトリガー条件として登録する場合、LINEメッセージが大量に配信される場合があります。

##### 指定された時刻に配信

指定した時刻にLINEメッセージを一斉配信できます。

配信頻度は、**一度だけ**、**毎日**、**毎週**、**毎月**から指定します。

###### 一度だけ配信する

配信日時を指定し、1度だけ配信できます。
現在時刻より、過去の日付や、15分以内の配信時刻は設定できません。



###### 毎日配信する

配信期間と配信時刻を指定し、毎日LINEメッセージを一斉配信できます。
以下の例では、2024年8月1日から8月31日まで毎日9時にLINEメッセージが一斉配信されます。
また、 `終了日を指定しない` にチェックを入れた場合はキャンペーンが非公開(停止)状態にされるまで配信されます。



###### 毎週配信する

配信期間と配信曜日、配信時刻を指定し、毎週LINEメッセージを一斉配信できます。
以下の例では、2024年8月1日から8月31日まで毎週月曜日(8月5日、8月12日、8月19日、8月26日)の9時にLINEメッセージが一斉配信されます。
また、 `終了日を指定しない` にチェックを入れた場合はキャンペーンが非公開(停止)状態にされるまで配信されます。



###### 毎月配信する

配信期間と毎月何日に配信するか、配信時刻を指定し毎月LINEメッセージを一斉配信できます。
以下の例では、2024年1月1日から2024月12月1日まで毎月1日の9時にLINEメッセージが一斉配信されます。
また、 `終了日を指定しない` にチェックを入れた場合はキャンペーンが非公開(停止)状態にされるまで配信されます。



##### 公開後すぐに配信を開始

キャンペーンを公開後、すぐにLINEメッセージを配信します。



### コンテンツの内容を入力する

#### 作成モード



LINEメッセージは「**スタンダード**」と「**カスタム**」の2つの作成モードがあります。

##### スタンダード

簡単に操作できるビジュアルエディタでコンテンツを作成します。
作成したメッセージはトークルーム、トークリストの2つのプレビューモードでプレビューできます。

対応するメッセージタイプ

- テキストメッセージ
- 画像メッセージ
- リッチメッセージ
- カードタイプメッセージ
- リッチビデオメッセージ

##### カスタム

JSONでコンテンツを作成します。スタンダードに対応していないタイプのメッセージの配信や、flexメッセージを利用した柔軟なレイアウトのメッセージ配信に対応しています。

対応するメッセージタイプ

- LINE Messaging APIで送信できるすべてのタイプ

##### NOTE
- スタンダードからカスタムにモードを切り替える場合、切り替えた時点でのスタンダードの設定内容がJSONとしてカスタムに引き継がれます。
- カスタムで編集した内容をスタンダードに引き継ぐことはできません。
- 下書き以外のキャンペーンでは、モードを切り替えることはできません。
- いずれのモードでもメッセージは5つまで同時に配信できます。
  - `[]` 内に複数のメッセージのJSONをカンマ区切りで入力することで、5つのメッセージまで同時に配信できます。
  - 同時に配信した場合は、LINEメッセージの配信数は1配信としてカウントされます。

#### テキストメッセージを作成する



テキストメッセージは、LINEメッセージで最も基本的なメッセージ形式です。文章のみで構成され、シンプルに情報や案内を伝えられます。
`[絵文字]` ボタンをクリックすると絵文字を選択して挿入できます。

##### NOTE
- 1メッセージにつき、5000文字まで入力できます。
- URLを入力した場合、自動的にリンクが付与されます。



#### 画像メッセージを作成する



画像メッセージは、1枚の画像を送信できるシンプルなメッセージです。商品画像やキャンペーンビジュアルを効果的に訴求できます。
ユーザーがトーク画面に表示される画像をタップすると、拡大可能なオリジナルの画像が表示されます。

##### 画像をアップロードする



`[画像をアップロード]` ボタンをクリックして画像をアップロードします。

##### NOTE
- ファイル形式: JPG、JPEG、PNG
- ファイルサイズ: 10MB以下
- 画像の解像度に制限はありません。

#### リッチメッセージを作成する



リッチメッセージは、画像とリンクを組み合わせた視覚的なメッセージです。テキストよりも印象的に情報を伝えられ、クリック率やコンバージョン率の向上に効果的です。

##### 代替テキストを入力する



代替テキストは、ユーザーがメッセージを受信した際に通知やトークリストに表示されるテキストです。
プレビューの\`\`トークリスト\`\`タブに切り替えることで表示をプレビューできます。

##### NOTE
- 代替テキストは必ず入力する必要があります。

##### テンプレートを選択する



リッチメッセージではエリアを最大4つまで割り当て、それぞれのエリアにリンクアクションやメッセージアクションを設定できます。
テンプレートによって、様々なレイアウトでアクションを設定できます。
利用したい任意のテンプレートをクリックし、`[選択]` をクリックします。

##### 正方形のテンプレート



##### 横長のテンプレート



##### 縦長のテンプレート



##### カスタムテンプレート



カスタムテンプレートは幅は1040px固定、高さが520~2080pxまでの自由なサイズの画像を利用できます。

##### NOTE
- 画像はJPEG/PNGタイプのみに対応しています、GIFやWebP等には対応していません。
- 画像の解像度はテンプレートで指定されたサイズ以外は利用できません。
- 画像の最大ファイルサイズは10MBです。

##### テンプレートのエリアにアクションを設定する

**URLアクション**



エリアをタップした際に入力したURLに遷移します。

**アクションラベル(任意項目)**
ユーザーデバイスのアクセシビリティ機能が有効な場合に読み上げられます。
最大100文字まで入力可能です、URL等の遷移先の説明や概要を入力してください。

##### NOTE
- URLにディープリンクは設定できません。

**テキストアクション**



**テキスト**
このエリアをタップ、クリックした際に入力したテキストがトークルームに送信されます。
応答メッセージのキーワードと一致するテキストを設定しておくと、そのキーワードを受信した際に事前に設定しておいたメッセージを自動で返信できます。

**アクションラベル(任意項目)**
ユーザーデバイスのアクセシビリティ機能が有効な場合に読み上げられます。
最大100文字まで入力可能です、メッセージ内容の説明や概要を入力してください。

すべてのエリアにアクションの設定が完了したらリッチメッセージの設定は完了です。

#### カードタイプメッセージを作成する



カードタイプメッセージは、カルーセル形式で複数のコンテンツを1つにまとめて送信できるメッセージです。

##### 代替テキストを入力する



代替テキストは、端末の通知、トークリスト、引用メッセージで表示されるテキストです。

##### NOTE
- 代替テキストは必ず入力する必要があります。
- 最大1500文字まで入力できます。

##### カードタイプを選択する



カードタイプは「**プロダクト**」と「**イメージ**」の2種類から選択できます。
`[カードタイプを変更]` ボタンをクリックするとダイアログが表示され、カードタイプを選択できます。

##### WARNING
- カードタイプを変更すると、現在のカードの内容が破棄されます。

###### プロダクト



プロダクトタイプは、商品やメニューの紹介に優れたカードタイプです。カードタイプの中では一番スタンダードなタイプで、用途に合わせて柔軟に活用できます。

画像、タグ、タイトル、説明文、価格、アクションボタンを設定できます。 必須項目以外はチェックボックスで表示/非表示を切り替えられます。

| 項目 | 必須 | 説明 |
| --- | --- | --- |
| 画像 | ○ | カードに表示する画像をアップロードします。ファイル形式はJPG、JPEG、PNG、ファイルサイズは10MB以下です。 |
| タグ |  | 画像の左上に表示するタグテキストを入力します。背景色はカラーピッカーでカスタマイズできます。 |
| カードのタイトル | ○ | 商品名などのタイトルを入力します。 |
| 説明文 |  | 商品の説明文を入力します。 |
| 価格 |  | 価格と通貨記号を設定します。 |
| アクション1 |  | ボタンのラベルとボタンとカード全体のタップ時のアクション（URLまたはテキスト送信）を設定します。 |
| アクション2 |  | 2つ目のアクションボタンを設定できます。 |

###### イメージ



イメージタイプはキャンペーンや商品などの写真をメインにした紹介に向いています。
画像、タグ、アクションボタンを設定できます。

| 項目 | 必須 | 説明 |
| --- | --- | --- |
| 画像 | ○ | カードに表示する画像をアップロードします。ファイル形式はJPG、JPEG、PNG、ファイルサイズは10MB以下です。 |
| タグ |  | 画像の左上に表示するタグテキストを入力します。背景色はカラーピッカーでカスタマイズできます。 |
| アクション |  | ボタンのテキストと、タップ時のアクションを設定できます。 アクション1で設定したアクションはカード全体に適用されます。 例: アクション1にURL1を、アクション2にURL2を設定した場合、アクション2をタップした際はURL2に遷移します。 アクション2以外の画像やタイトル、アクション1部分をタップした際はURL1 に遷移します。 |

##### カードを追加・編集する



`[カード追加]` ボタンをクリックしてカードを追加します。カードタブもしくはカルーセルに表示される矢印をクリックすると、編集するカードを切り替えられます。

##### NOTE
- 最大9枚までカードを追加できます。
- 保存時にエラーがある場合、最初のエラーがあるカードに自動的にフォーカスされます。
- 入力エラーがあるカードは、タブに赤い枠線で表示されます。

##### もっとみるカードを追加する



`[もっとみる追加]` ボタンをクリックすると、カルーセルの最後に「もっとみる」カードを追加できます。
「もっとみるカード」を使うことで、興味を持ったユーザーを自社サイトなどに誘導し詳細情報を伝えることが可能です。

| 項目 | 必須 | 説明 |
| --- | --- | --- |
| アクション | ○ | カードに表示するテキスト（「もっとみる」など）を入力します。 |
| タイプ | ○ | タップ時のアクションタイプ（URLまたはテキスト送信）を選択します。 |
| URL/テキスト | ○ | URLの場合は遷移先を、テキストの場合は送信するメッセージを入力します。 |

##### NOTE
- URLのスキームはhttpsのみ対応しています。

##### カードを削除する



カードタブの `[×]` ボタンをクリックすると、カードを削除できます。削除前に確認ダイアログが表示されます。

##### NOTE
- 最低1枚のカードが必要です。すべてのカードを削除することはできません。

#### リッチビデオメッセージを作成する



リッチビデオメッセージは、動画を配信できるメッセージです。動画は自動再生またはユーザのタップで再生され、再生終了後に任意のアクションを促すことができます。動画を見終わったユーザーをそのまま任意のアクションに誘導できるため、動画で紹介した商品ページや企業のホームページのリンクを表示させることで、高い誘導効果に期待できます。

##### NOTE
- 一定以上に縦長・横長の動画を送信した場合、一部の環境では動画の一部が欠けて表示される場合があります。
- 動画を使用できるLINEのバージョンは以下のとおりです。
  - iOS版とAndroid版のLINE: 11.22.0以降
  - macOS版とWindows版のLINE: 7.7.0以降
- LINEのバージョンが動画をサポートするバージョンに満たない場合、プレビュー画像が表示されます。

##### 代替テキストを入力する



代替テキストは、端末の通知、トークリスト、引用メッセージで表示されるテキストです。

##### NOTE
- 代替テキストは必ず入力する必要があります。
- 最大1500文字まで入力できます。

##### 動画URLを入力する



お客様がCDN等で管理されている動画のURLを入力します。HTTPS URLのみ対応しています。

##### NOTE
- ファイル形式: MP4
- ファイルサイズ: 200MB以下
- プレビュー画像と同じアスペクト比の動画を使用してください。

##### プレビュー画像をアップロードする



動画再生前に表示されるサムネイル画像をアップロードします。
動画と同じアスペクト比の画像を使用してください。異なる場合、端末によっては動画の一部が欠けて表示されることがあります。

##### NOTE
- ファイル形式: JPG、JPEG、PNG
- ファイルサイズ: 10MB以下
- 高さには幅の3倍を超える値は指定できません。
- 動画をホストしているサーバーが、HTTPの範囲リクエスト（Range request）に対応している必要があります。

##### アクションを設定する（任意）



アクションボタンを設定すると、自動再生の場合は動画終了後、タップ再生の場合は動画再生中と終了後にアクションボタンが表示されます。

- **URL**
  タップ時に開かれるURLを入力します。HTTPS URLのみ対応しています。
- **アクションボタンテキスト**
  アクションボタンに表示されるテキストを入力します。

### 配信する

キャンペーンの情報を入力後、キャンペーンを公開します。
配信設定、コンテンツで指定した内容でメッセージが配信されます。

##### WARNING
- ユーザーに配信する前に、必ずテスト配信を行いメッセージが正しく表示されるか、リンク先に正しく遷移されるかを確認してください。

### LINEメッセージのキャンペーンの効果測定を確認する

#### 配信結果



##### 効果測定値

- **ユニークユーザー数**
  配信結果にある項目をユーザー単位で集計した数値
- **総回数**
  配信結果を集計した数値。
- **配信数**
  LINE MessagingAPIに受理されたメッセージ数
- **CV数**
  配信から24時間以内にCVしたUU
- **CV率**
  `CV数 / 開封数`

#### 効果測定データをダウンロードする

配信結果の右上にあるボタンから、公開からの全期間のデータをCSVとしてダウンロードできます。

---

## ReproへのLINEユーザーIDの登録

### ReproへのLINEユーザーIDの登録方法

LINEユーザーIDは、以下の3つの方法でReproに登録できます。

1. 管理画面からのインポート
   - CSVファイルを使用し、LINEユーザーIDを一括で登録します。初回の登録に最も簡単な方法です。
2. S3による自動インポート
   - CDPや社内システムから生成したCSVファイルをS3にアップロードすることで、Reproが自動的にLINEユーザーIDを取り込みます。
3. Web/iOS/Android SDKを利用して登録
   - アプリやWebサイトにRepro SDKを組み込み、ユーザー操作に応じてLINEユーザーIDをリアルタイムでReproに送信します。

#### 推奨構成

初回は管理画面インポートによりベースデータを登録し、

以降の運用では SDK または S3インポート による自動更新を組み合わせる方法を推奨しています。

これにより、最新のLINEユーザーID情報を常にReproと同期させることができます。

### 共通の準備事項

#### LINEユーザーIDとユーザーIDの準備

CDPや社内システム等からReproのSDKでセットしている [ユーザーID](https://docs.repro.io/ja/dev/sdk/user-id.html) と [LINEユーザーID](https://developers.line.biz/ja/docs/messaging-api/getting-user-ids) を後述するCSVフォーマットに沿って出力します。
ユーザーIDも同時にインポートして紐付けを行う場合は、あらかじめ [ユーザーアカウントの連携](https://developers.line.biz/ja/docs/messaging-api/linking-accounts/) 等の方法でユーザーIDとLINEユーザーの連携が必要です。
ReproのユーザーIDとの紐付けが不要な場合は、LINEユーザーIDのみを含むCSVでインポートできます。

##### WARNING
- LINEのユーザーIDは、LINEで登録されているユーザーの表示名や、 [LINEでの友だち検索に利用するLINE ID](https://guide.line.me/ja/account-and-settings/account-and-profile/set-line-id.html) とは異なります。



#### CSVフォーマット

CSVファイルは以下の2つの形式に対応しています。

**形式1: LINEユーザーIDとユーザーID（推奨）**

```
line_user_id,user_id
Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,dummy_user_id_000000000001
Uyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy,dummy_user_id_000000000002
...
```

**形式2: LINEユーザーIDのみ**

```
line_user_id
Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Uyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
...
```

- ヘッダー
  - **1行目には必ずヘッダーの指定が必要です**
  - `line_user_id` は必須です。 `user_id` は任意です。
- データの内容
  - **line_user_id**
    - [LINEのユーザーID](https://developers.line.biz/ja/docs/messaging-api/getting-user-ids) (Uから始まる英数33文字)
    - 必須項目
  - **user_id**
    - [ユーザーID](https://docs.repro.io/ja/dev/sdk/user-id.md) (SDKからユーザーIDとしてセットした値)
    - 上限191文字
    - 任意項目（省略可能）
- ファイルサイズ上限
  - 500MB
- 文字エンコーディング
  - UTF-8 (BOMなし)



#### インポート種別

LINEユーザーIDのインポートには、以下の2つの種別があります。

- **配信可能ユーザーとしてインポート**: 友だち登録済みの配信可能なユーザーとしてインポートします。
- **ブロックユーザーとしてインポート**: ブロック済みのユーザーとしてインポートします。ブロックユーザーはLINE配信の対象から除外されます。

管理画面からのインポート・S3による自動インポートいずれの方法でも、インポート時にこの種別を指定します。

#### 一般的なインポートパターン

LINEユーザーIDのインポートには、組織のシステム環境やブロック情報の管理状況に応じて、以下のようなパターンがあります。

**パターン1: 自社システムにブロック情報がなく、Repro以外のLINE配信ツール上にのみブロック情報がある場合**

このパターンでは、配信可能ユーザーとブロックユーザーを別々にインポートする必要があります。

1. 自社システムやCDP等から形式1（LINEユーザーID、ユーザーID）で、ブロックユーザーも含めた全ユーザー分を取得し、Reproに **配信可能ユーザーとしてインポート** します。
2. LINE配信ツールから形式2（LINEユーザーIDのみ）でブロックユーザーを取得し、Reproに **ブロックユーザーとしてインポート** します。

**パターン2: 自社システム上にブロック情報を管理している場合**

このパターンでは、あらかじめブロックユーザーを除外したリストをインポートします。

1. 自社システムやCDP等から形式1（LINEユーザーID、ユーザーID）で、ブロックユーザーを除外したユーザー分を取得し、Reproに **配信可能ユーザーとしてインポート** します。

**パターン3: ブロックユーザー情報を保持していない場合**

このパターンでは、LINE Messaging APIを利用してブロック状態を確認し、配信可能ユーザーのみをインポートします。

1. 自社システムやCDP等から形式1（LINEユーザーID、ユーザーID）で全ユーザー分を取得します。
2. LINE Messaging APIの [Get follower IDs API](https://developers.line.biz/ja/reference/messaging-api/#get-follower-ids) を利用して、ブロックされていない友だち一覧を取得します。
3. 1と2のリストを突合し、ブロックユーザーを除外したリストをReproに **配信可能ユーザーとしてインポート** します。

##### NOTE
- いずれのパターンでも、初回インポート後も定期的にユーザー情報を更新することで、常に最新の配信可能ユーザーリストを維持できます。

#### インポート時の動作について

- **配信可能ユーザーとして形式2（LINEユーザーIDのみ）でインポートした場合**: ReproのユーザーIDとの紐付けは行われません。この場合、既存ユーザーへの一斉配信のみ可能で、セグメントを利用した配信はできません。ユーザーIDと紐付けてセグメント配信を行いたい場合は、形式1を使用してください。
- **ブロックユーザーとしてインポートした場合**: すでに配信可能ユーザーとして形式1でインポート済みのユーザーについては、そのユーザーのブロック状態が更新されます。
- **インポート後のブロック状態の確認**: [ID指定オーディエンス](https://docs.repro.io/ja/dashboard/campaign/audience.md) を利用してLINEユーザーIDまたはユーザーIDで検索することで、個別のユーザーのブロック状態を確認できます。

### 管理画面からインポートする

1. [設定] > [LINE設定] > [LINE配信用ユーザー情報インポート] にアクセスします。
   
2. インポート先のLINEチャネルを選択します。
   
3. [インポートするLINEユーザーIDの種別] で、 [インポート種別](#import-type-section) を選択します。
4. CSVファイルを選択し、[インポート]をクリックします。
5. アップロードしたCSVのステータスが `アップロード中` → `インポート完了` になれば完了です。
   

##### WARNING
- ステータスは自動的に更新されません。ブラウザを更新してご確認ください。
- ステータスがエラーになった場合、エラーの内容がメールで送信されます。
  - エラーの内容を修正後、再度インポートし直してください。

### S3による自動インポート

Reproの提供するAWS S3 bucketに対してCSVファイルをアップロードすることで、LINE配信用ユーザー情報の登録を行うことができます。

##### NOTE
- 利用する際には、Reproの提供するAWS S3 bucketに対してオブジェクトをアップロードするための認証情報を事前に発行する必要があります。詳細については [こちら](https://docs.repro.io/ja/dev/user-profile-bulk-import-api/index.md#user-profile-bulk-import-s3) の項目をご確認ください。

#### S3 パス構造と各パラメータの説明

以下の形式でアップロードします。

**配信可能ユーザーとしてインポート**

```
s3://repro-data-store/<YOUR_APP_ID>/line_user_id/<line_channel_id>/<year>/<month>/<day>/followed/<file_name>.csv
```

**ブロックユーザーとしてインポート**

```
s3://repro-data-store/<YOUR_APP_ID>/line_user_id/<line_channel_id>/<year>/<month>/<day>/unfollowed/<file_name>.csv
```

各項目の意味

| 項目 | 説明 |
| --- | --- |
| `<YOUR_APP_ID>` | Repro 管理画面で付与されるアプリケーション ID |
| `<line_channel_id>` | 対象となる LINE チャネルの Channel ID |
| `<year>/<month>/<day>` | ファイルアップロード日。 `yyyy/mm/dd` 形式で必須 |
| `followed` / `unfollowed` | インポート種別。 `followed` は配信可能ユーザーとしてインポートします。 `unfollowed` はブロックユーザーとしてインポートし、LINE配信の対象から除外します。 |
| `<file_name>` | アップロードする CSV ファイル名 |

##### NOTE
- `<line_channel_id>` は、 **[設定] > [LINE設定] > [LINEチャネル設定]** ページから確認することができます。

##### WARNING
- アップロードするCSVファイルは、名前に `/` 及び空白文字を含めることはできません。

#### CSVフォーマット

CSV ファイルの形式については、 [CSVフォーマット](#csv-format-section) セクションを参照してください。

#### アップロード例

例として、AWS CLIを利用した場合には以下のようなコマンドでCSVをS3にアップロードできます。

**配信可能ユーザーとしてインポートする場合**

```sh
$ export AWS_ACCESS_KEY_ID=AKIAXXXXXXX
$ export AWS_SECRET_ACCESS_KEY=XXXXXX
$ aws s3 cp line_user_ids.csv s3://repro-data-store/<YOUR_APP_ID>/line_user_id/<line_channel_id>/<year>/<month>/<day>/followed/line_user_ids.csv
```

**ブロックユーザーとしてインポートする場合**

```sh
$ export AWS_ACCESS_KEY_ID=AKIAXXXXXXX
$ export AWS_SECRET_ACCESS_KEY=XXXXXX
$ aws s3 cp blocked_user_ids.csv s3://repro-data-store/<YOUR_APP_ID>/line_user_id/<line_channel_id>/<year>/<month>/<day>/unfollowed/blocked_user_ids.csv
```

#### インポートのタイミング・頻度

- S3バケットへのファイルアップロードをトリガーとして自動的にインポート処理が開始されます。
- 頻度に制限はなく、複数ファイルを並行してアップロードできます。
  - ただし、S3パスとファイル名が同じ場合、最初にアップロードしたデータが処理されず最後にアップロードしたデータが複数回処理されることがあります。同日に同名のファイルをアップロードしたい場合は、各ファイル名を変更してください。

#### よくあるご質問

- ファイルのアップロードが完了したかはどのように知ることができますか？
  - インポート処理が完了すると、インポートしたLINE配信用ユーザーファイルの情報を記載した通知メールが送信されます。エラーが発生した場合は、エラー用CSVファイルのダウンロードリンクも合わせて記載されます。
- S3パスに含まれる year、month、dayはいずれも指定が必須ですか？
  - 全て指定が必須です。ファイルアップロード日を yyyy/mm/dd（例：2025/04/30） 形式で指定するようにしてください。
- S3へのアップロード中、さらに別のファイルをアップロードすることは可能ですか？
  - 可能です。並行して複数ファイルのアップロードができます。
  - ただし、S3パスとファイル名が同じ場合、最初にアップロードしたデータが処理されず最後にアップロードしたデータが複数回処理されることがあります。同日に同名のファイルをアップロードしたい場合は、各ファイル名を変更してください。

### Web/iOS/Android SDKを利用して登録

アプリやWebサイトからSDKを利用してLINEユーザーIDを登録することができます。
この方法で登録を行うと、ユーザーのLINEユーザーIDを取得してすぐにLINEメッセージを配信できます。

詳細な実装方法については、以下のドキュメントをご確認ください

**iOS/Android**: [ReproへのLINEユーザーIDの登録 (iOS/Android SDK)](https://docs.repro.io/ja/dev/sdk/line-integration.md)

**Web**: [ReproへのLINEユーザーIDの登録 (Web SDK)](https://docs.repro.io/ja/dev/web/line-integration.md)

---

## ユーザープロフィールバルクインポート

ユーザープロフィールバルクインポートを使うと、自社のデータベースにのみ保持しているユーザーの属性情報（会員ランクや、LTV、性別、Emailなど）をCSVとしてアップロードすることで、一括してユーザープロフィールに登録できます。

アップロードしたCSVは順次処理され、ユーザープロフィールが更新されます。
更新されたユーザープロフィールの更新情報はメールにて通知されます。
処理時間はアップロードするCSVのサイズや、更新するユーザープロフィール数によって異なります。

### はじめに



#### CSVファイルについて

ユーザープロフィールバルクインポートでは、CSVファイルを利用してユーザープロフィールの更新を行います。

##### ファイルフォーマット

```
user_id,birthday,name,point
123456,2000-01-01T00:00:00+09:00,foo,123
234567,2001-02-01T00:00:00+09:00,bar,234
```

###### ヘッダとカラム

1行目に指定したヘッダの値をユーザープロフィールのkeyとして登録します。

- `user_id`: アプリやWebサイト内で [ユーザーID](https://docs.repro.io/ja/dev/sdk/user-id.md) APIを使って登録されたユーザーのIDを指定します。必須項目です。
- `REPRO_ERRORS` というカラム名は、後記するエラーメッセージの出力に使用されます。そのため、記述されていても `REPRO_ERRORS` というユーザープロフィールは作成されず、値は無視されます。
- その他のカラムは、ヘッダに指定した値をkey、2行目以降の値をvalueのユーザープロフィールとして扱います。
- ヘッダに指定するkeyは空文字は不可、上限は255文字です。
- 文字コードはUTF-8エンコーディングとして扱います。
- keyやvalueの前後の空白は自動的に除去せずそのまま扱います。
- 指定されなかったkeyのvalueは更新されません。
- valueが空の場合は、指定したユーザーIDのユーザープロフィールは更新されません。

###### 型

Reproのユーザープロフィールには4つの型が存在しますが、CSVには型が存在しないため、以下のルールに沿ってカラムの型を決定します。

1. 既に登録されている `user profile key` は、既存の型をそのまま使います。
2. 未知のkeyの場合、csvファイルを一定数読み込み、値から型を決定します。
   1. `iso8601 format` に沿っていれば `datetime` とします。
   2. 小数点を含む数字のみなら `decimal` 型とします。
   3. 数字のみなら `int` 型とします。
   4. それ以外はすべて `string` 型とします。
3. ルールに沿わない値がある行は、エラー情報のカラムを追加してエラー用のCSVファイルを書き出し、ダウンロードリンクを付与したメールが送信されます。



### 管理画面アップロード

管理画面からユーザープロフィールを記載したCSVファイルをアップロードすることができます。

##### WARNING
管理画面からのCSVアップロードでは、250MBまでのCSVファイルをアップロードすることができます。

#### 管理画面からユーザープロフィールを記載したCSVファイルをアップロードする

1. **ユーザープロフィール > データインポート** ページにアクセスします。
2. 「CSVファイルをアップロード」ボタンをクリックし、アップロードするCSVファイルを選択します。





### S3アップロード

Reproの提供するAWS S3 bucketに対してCSVファイルをアップロードすることで、ユーザープロフィールの登録を行うことができます。

##### NOTE
利用する際には、Reproの提供するAWS S3 bucketに対してオブジェクトをアップロードするための認証情報を事前に発行する必要があります。詳細については [AWS S3 bucketにアップロードするためのアクセスキーを作成する](#id8) の項目をご確認ください。

アップロードするS3 bucket、パスについては、 **ユーザープロフィール > データインポート** から確認することができます。

##### WARNING
- アップロードするCSVファイルは、名前に / 及び空白文字を含めることはできません
- アップロードするCSVファイルは、1GBまでのサイズである必要があります

例として、AWS CLIを利用した場合には以下のようなコマンドでユーザープロフィールの記載されたCSVをS3にアップロードできます。

```sh
$ export AWS_ACCESS_KEY_ID=AKIAXXXXXXX
$ export AWS_SECRET_ACCESS_KEY=XXXXXX
$ aws s3 cp user_profiles.csv s3://repro-data-store/XXXXXXX/user_profile_bulk_import/user_profiles.csv
```

利用しているプロジェクトごとにアップロードするS3パスは異なります。
**ユーザープロフィール > データインポート** ページ下部の「Amazon S3 パス」に記載されているものをお使いください。



#### AWS S3 bucketにアップロードするためのアクセスキーを作成する

1. **設定 > プロジェクト設定** に行き、 **「認証情報」タブ** に切り替えます。
2. 「AMAZON S3 アクセスキーを追加」ボタンをクリックしてください。

> 
1. ボタンをクリックするとポップアップが出現するので、表示された「アクセスキーID」と「シークレットアクセスキー」を大切に保管してください。(※シークレットアクセスキーはポップアップを閉じると二度と表示されません)

> 



### ユーザープロフィールバルクインポートAPI v3

#### ユーザープロフィールAPIとの違い

[ユーザープロフィールAPI](https://docs.repro.io/ja/dev/user-profile-api/index.md) は、1回のリクエストで1ユーザーのユーザープロフィールを登録するのに対して、ユーザープロフィールバルクインポートAPIはCSVに含まれる複数ユーザーのユーザープロフィールを登録できます。
ユーザープロフィールバルクインポートAPIは既存データの反映など、即時性は求められないが一度に大量のデータ更新が必要な場合に適します。

##### NOTE
- ユーザープロフィールバルクインポートAPIでは、[標準ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md#standard-user-profile) を更新することはできません。



#### Repro API トークンの取得

ユーザープロフィールバルクインポートAPIを使うには、Repro API トークンを利用する必要があります。

1. **設定 > プロジェクト設定** に行き、 **認証情報 > Repro API トークン** を確認します。



##### WARNING
「APIトークンの再発行」をすると既存のAPIトークンを利用できなくなり、あとから復元することはできません。

#### 単位時間あたりのアクセス上限

ユーザープロフィールバルクインポートAPIには、単位時間当たりのアクセス上限があります。

- アクセス上限設定値は、APIトークンごとに10分あたり10件です。
- リクエストが正常に完了すると、レスポンスの `X-RateLimit-Limit` ヘッダーに単位時間あたりのリクエスト上限回数が記載されます。
- リクエスト数がアクセス上限数を超えると、 `HTTP Status 429 (Too Many Requests)` が返ります。

レスポンスヘッダーの詳細は [レスポンス](#user-profile-bulk-import-api-response) を確認してください。

##### WARNING
- アクセス上限設定値は予告なく変動する場合があります。
- アクセス上限設定値は、機能単位でのAPIトークンごととなります。
   
  例えば、プッシュAPIとユーザープロフィールAPIは同じAPIトークンを利用していますが、別機能のため同時にリクエストしたとしても、それぞれ１件づつのカウントとなります。
   

ユーザープロフィールバルクインポートAPI v3では、ユーザープロフィールを更新するために異なるエンドポイントに対して 2 回リクエストを送る必要があります。

1. `POST /v3/user_profiles/bulk_import` を実行し、S3にダイレクトアップロードするためのpre-signed URLを取得する
2. `PUT <pre-signed URL>` を実行し、S3にファイルをアップロードする

##### NOTE
pre-signed URLの有効期限は5分です。そのため、1回目のレスポンスを受け取ってから5分以内に2回目のリクエストを開始してください。

#### サンプルコード

ユーザープロフィールバルクインポートAPI v3にリクエストを行うサンプルコードを以下に記載します。

```sh
#!/bin/bash

set -e

API_TOKEN="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

URI="https://api.reproio.com/v3/user_profiles/bulk_import"

file=$(realpath -e $1)
checksum=$(openssl dgst -md5 -binary ${file} | base64)
content_size=$(stat -c %s ${file})

body=$(cat <<EOF
{
  "checksum": "${checksum}",
  "byte_size": "${content_size}"
}
EOF
)

# First request
response=$(curl -X POST \
                -H "X-Repro-Token: ${API_TOKEN}" \
                -H "Content-Type: application/json" \
                --data "${body}" \
                ${URI})

# Get the value needed for the second request from the response
url=$(echo ${response} | jq -r .direct_upload.url)
content_type=$(echo ${response} | jq -r '.direct_upload.headers["Content-Type"]')
content_md5=$(echo ${response} | jq -r '.direct_upload.headers["Content-MD5"]')

echo $response

# Second request
curl -X PUT \
    -H "Content-Type: ${content_type}" \
    -H "Content-MD5: ${content_md5}" \
    --upload-file ${file} \
    "${url}"

echo done
```

#### 1回目のリクエスト

##### エンドポイント

| HTTPメソッド | エンドポイント |
| --- | --- |
| `POST` | `https://api.reproio.com/v3/user_profiles/bulk_import` |

##### リクエストヘッダー

| ヘッダー | 説明 | 任意 / 必須 |
| --- | --- | --- |
| Content-Type | application/jsonを指定します。 | 必須 |
| X-Repro-Token | [Repro API トークンの確認](https://docs.repro.io/ja/dev/audience-api/index.md#repro-api-token) で取得したトークンを指定します。 | 必須 |

##### リクエストパラメータ

| フィールド | 説明 | 任意 / 必須 |
| --- | --- | --- |
| checksum | [インポートに利用するファイル](#user-profile-bulk-import-csv-format) のmd5 checksumをbase64エンコードしたもの。 `openssl dgst -md5 -binary hoge.csv | base64` で算出することができます。 | 必須 |
| content_type | `text/csv` または `application/gzip` を指定。省略すると `text/csv` になります。 | 任意 |
| byte_size | [インポートに利用するファイル](#user-profile-bulk-import-csv-format) のファイルサイズ | 必須 |

##### ペイロード例

**CSVファイルをアップロードする場合**

```json
{
  "checksum": "J1h240z2CdsRjz2Et5mnkA==",
  "byte_size": "123456"
}
```

**gzip 圧縮したファイルをアップロードする場合**

```json
{
  "checksum": "J1h240z2CdsRjz2Et5mnkA==",
  "content_type": "application/gzip",
  "byte_size": "12345"
}
```

##### レスポンスヘッダー

レスポンスのヘッダーには、以下の値が含まれます。

| ステータス | ヘッダー | 説明 |
| --- | --- | --- |
| 正常 | `X-RateLimit-Limit` | 単位時間あたりのアクセス上限 |
| 正常 | `X-RateLimit-Remaining` | アクセスできる残り回数 |
| 正常 | `X-RateLimit-Reset` | アクセス数がリセットされる時刻(unixtime) |
| リクエスト制限 | `Retry-After` | 再実行可能になるまでの秒数 |

##### 正常系レスポンス

リクエスト成功時、レスポンスボディはJSON形式で以下の内容が返ってきます。

| フィールド | 説明 |
| --- | --- |
| response.direct_upload | 2回目のリクエストに必要な情報を格納したオブジェクト |
| response.direct_upload.url | 2回目のリクエストのエンドポイントURL |
| response.direct_upload.headers | 2回目のリクエストに必要なヘッダー情報 |

##### 正常系レスポンスボディ例

```json
{
  "direct_upload": {
    "url": "https://repro-direct-upload-production.s3.ap-northeast-1.amazonaws.com/6pWMZB1797H4bNVqTwFDcPzX?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAITZGHBHURRYGMYHA%2F20200618%2Fap-northeast-1%2Fs3%2Faws4_request&X-Amz-Date=20200618T011630Z&X-Amz-Expires=300&X-Amz-SignedHeaders=content-md5%3Bcontent-type%3Bhost&X-Amz-Signature=2902f97f060894f900141b4dde2ca2bfae9de2bd8ff3c6e3f098eab6faf674d6",
    "headers": {
      "Content-Type": "text/csv",
      "Content-MD5": "QYLqokRq51xGBqakDLsBvA=="
    }
  }
}
```

##### エラーレスポンス

レスポンスに含まれるステータスコードとエラーメッセージの一覧は下記になります。

##### 400 Bad Request

リクエストにエラーがあります。エラーメッセージを確認の上、対応してください。

checksumに不正な文字列が含まれています。

レスポンスボディ:

```json
{
  "error": {
    "messages": [
      "Validation failed: Checksum is invalid"
    ]
  }
}
```

byte_sizeが指定されていません。

レスポンスボディ:

```json
{
  "error": {
    "messages": [
      "param is missing or the value is empty: byte_size"
    ]
  }
}
```

##### 401 Unauthorized

Repro API トークンが指定されていません。

レスポンスボディ:

```json
{
  "status": "unauthorized",
  "error": {
    "messages": [
      "Please include your Repro API Token as \"X-Repro-Token\" HTTP header."
    ]
  }
}
```

##### 403 Forbidden

指定した Repro API トークンが間違っています。

レスポンスボディ:

```json
{
  "status": "forbidden",
  "error": {
    "messages": [
      "Please check your Repro API Token as \"X-Repro-Token\" HTTP header."
    ]
  }
}
```

##### 404 Not Found

エンドポイントが存在しません。

レスポンスボディ:

```json
{
  "status": "not_found",
  "error": {
    "messages": [
      "Not found."
    ]
  }
}
```

##### 429 Too Many Requests

リクエスト数が多すぎます。 `Retry-After` ヘッダーに記載された秒数待った後、リクエストを再開してください。

レスポンスボディ:

```json
{
  "status": "too_many_requests",
  "error": {
    "messages": [
      "Too many requests hit the API too quickly."
    ]
  }
}
```

#### 2回目のリクエスト

##### エンドポイント

| HTTPメソッド | エンドポイント |
| --- | --- |
| `PUT` | 1回目のリクエストが成功した場合、レスポンスに含まれる `response.direct_upload.url` の値 |

#### リクエストヘッダー

1回目のリクエストが成功した場合、レスポンスに含まれる `response.direct_upload.headers` の値全てをヘッダーとして指定してください。

#### リクエストパラメータ

ユーザープロフィールを更新するためのCSVファイルをセットしてください。
セット可能なファイルサイズの上限は以下となります。

- **csv**: 1 GB
- **gzip**: 100 MB

ファイルの形式については、[CSVファイルについて](#user-profile-bulk-import-csv-format) を確認してください。

#### 正常系レスポンス

リクエストに成功したら、 `200` のステータスコードが返されます。

#### エラーレスポンス

エラーレスポンスについては [こちら](https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html) のドキュメントを参照してください。



##### インポート完了通知メール

**概要**

更新処理が完了すると、更新したユーザープロフィールの情報を記載した通知メールが送信されます。
エラーが発生した場合は、エラー用CSVファイルのダウンロードリンクも合わせて記載されます。



##### エラー用CSVファイル

**概要**

CSVをアップロードし、更新処理が実行された際にCSVの詳細なバリデーションを行います。
その際、正常に処理された行を除き、エラーが発生した行と `REPRO_ERRORS`
というエラー情報のカラムが追加されたCSVが [インポート完了通知メール](#user-profile-bulk-import-notify-mail) のリンクからダウンロードできます。リクエストに利用したファイルサイズが大きすぎたり、ファイルが空の場合にはエラー情報を記載したCSV内に `REPRO_ERRORS` カラムが存在しない場合もあります。
`REPRO_ERRORS` カラムが存在する場合は、 `REPRO_ERRORS` カラムの値は全て無視されるので、エラー用CSVの内容を修正しそのまま再度APIリクエストとして送信することもできます。

エラー用CSVファイルサンプル

```
REPRO_ERRORS,user_id,birthday,name,point
birthday should be iso8601 format,123456,2000-01-01 00:00:00.000,foo,123
point should be integer,234567,2001-02-01T00:00:00+09:00,bar,234.0
```

###### エラー詳細

| messages | 説明 |
| --- | --- |
| too many values | ヘッダーに対して値のカラム数が多すぎます。 |
| user_id is unregistered user | 指定されたuser_idをもつユーザーは登録されておりません。 |
| [column name] should be UTF-8 | UTF-8ではない値が指定されています。 |
| [column name] should be integer | int型ではない値が指定されています。 |
| [column name] should be decimal | decimal型ではない値が指定されています。 |
| [column name] should be iso8601 format | iso8601フォーマットではない値が指定されています。 |

##### NOTE
- エラーが全く発生しなかった場合はリンクは付与されません。



### (廃止予定)ユーザープロフィールバルクインポートAPI v2

##### WARNING
**本API v2は 2021年8月31日 に廃止予定です。** APIをご利用される場合は [ユーザープロフィールバルクインポートAPI v3](#user-profile-bulk-import-api-v3) をご利用ください。

#### APIフォーマット

**リクエストサンプル**

```
curl -X POST \
--verbose \
-H 'Content-Type: text/csv' \
-H 'X-Repro-Token:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' \
--data-binary '@sample.csv' \
'https://api.reproio.com/v2/user_profiles/bulk_import'
```

#### リクエスト

**リクエストヘッダー**

リクエストのヘッダーには、以下の値を設定します。

| ヘッダー | 説明 | 必須 |
| --- | --- | --- |
| Content-Type | CSVをPOSTする際は `Content-Type: text/csv` を、gzip済みのCSVをPOSTする際は `Content-Type: application/gzip` を指定します。 | 必須 |
| X-Repro-Token | [Repro API トークンの取得](#user-profile-bulk-import-api-get-api-token) で取得したトークンを指定します。 | 必須 |

**リクエストボディ**

CSV、またはgzipしたCSVをHTTP bodyにセットします。
CSVの詳細のフォーマットは、 [CSVファイルについて](#user-profile-bulk-import-csv-format) を確認してください。



#### レスポンス

**レスポンスヘッダー**

レスポンスのヘッダーには、以下の値が含まれます。

| ステータス | ヘッダー | 説明 |
| --- | --- | --- |
| 正常 | `X-RateLimit-Limit` | 単位時間あたりのアクセス上限 |
| 正常 | `X-RateLimit-Remaining` | アクセスできる残り回数 |
| 正常 | `X-RateLimit-Reset` | アクセス数がリセットされる時刻(unixtime) |
| リクエスト制限 | `Retry-After` | 再実行可能になるまでの秒数 |

**レスポンスボディ**

ユーザープロフィールバルクインポートAPIをコールした際の、レスポンスに含まれるステータスコードとエラーメッセージの一覧は下記になります。

##### 202 Accepted

リクエストが成功しました。
レスポンスボディには、POSTしたCSVのカラムの型推定の結果を返却します。

レスポンスボディ:

```json
{
  "user_profile": {
    "birthday": {
      "type": "datetime"
    },
    "name": {
      "type": "string"
    },
    "point": {
      "type": "int"
    }
  }
}
```

##### 400 Bad Request

レスポンスボディ:

```json
{
  "error": {
    "code": 2001,
    "messages": [
      "user_id column is required"
    ]
  }
}
```

**code 2001** CSVのフォーマットが不正です。 [CSVファイルについて](#user-profile-bulk-import-csv-format) を参考にし、フォーマットを確認してください。

| messages | 説明 |
| --- | --- |
| empty file | ファイルが空です。 POSTしているファイルの内容を確認してください。 |
| header size over 102400 bytes | CSVのヘッダーのサイズが100KBを超えています、100KB以内にしてください。 |
| newline character not found | 改行コードがありません。 |
| empty columns | カラムが空です。 |
| user_id column is required | CSVのヘッダーにuser_idカラムの指定がありません。 |
| [key name] should be UTF-8 | UTF-8以外の文字コードのデータが含まれています。 CSVはUTF-8でエンコードしてください。 |
| duplicate columns [key names] | 重複したカラム名は扱えません。 |

レスポンスボディ:

```json
{
  "error": {
    "messages": [
      "not in gzip format"
    ]
  }
}
```

POSTしたファイルはgzip形式ではありません。

レスポンスボディ:

```json
{
  "error": {
    "messages": [
      "file maybe corrupt"
    ]
  }
}
```

POSTしたgzipファイルが破損している可能性があります。

レスポンスボディ:

```json
{
  "error": {
    "messages": [
      "This app has exceeded the limit of enabled user profile(x)"
    ]
  }
}
```

ユーザープロフィール数の上限を超えています。

##### 401 Unauthorized

Repro API トークンが指定されていません。

レスポンスボディ:

```json
{
  "status": "unauthorized",
  "error": {
    "messages": [
      "Please include your Repro API Token as \"X-Repro-Token\" HTTP header."
    ]
  }
}
```

##### 403 Forbidden

指定した Repro API トークンが間違っています。

レスポンスボディ:

```json
{
  "status": "forbidden",
  "error": {
    "messages": [
      "Please check your Repro API Token as \"X-Repro-Token\" HTTP header."
    ]
  }
}
```

##### 404 Not Found

エンドポイントが存在しません。

レスポンスボディ:

```json
{
  "status": "not_found",
  "error": {
    "messages": [
      "Not found."
    ]
  }
}
```

##### 413 Payload Too Large

POSTしたCSVのサイズが大きすぎます。

レスポンスボディ:

```json
{
  "error": {
    "messages": [
      "client intended to send too large body"
    ]
  }
}
```

##### 415 Unsupported Media Type

受理できないフォーマットのデータが含まれています。 リクエストヘッダの
`Content-Type` やエンドポイントに誤りがないか確認してください。

レスポンスボディ:

```json
{
  "error": "415 Unsupported Media Type"
}
```

##### 429 Too Many Requests

リクエスト数が多すぎます。 `Retry-After`
ヘッダーに記載された秒数待った後、リクエストを再開してください。

レスポンスボディ:

```json
{
  "status": "too_many_requests",
  "error": {
    "messages": [
      "Too many requests hit the API too quickly."
    ]
  }
}
```

#### インポート完了通知メール

[こちら](#user-profile-bulk-import-notify-mail) を確認してください。

---

## ユーザープロフィールAPI

ユーザープロフィールAPIを使うと、自社のデータベースにのみ保持しているユーザーの属性情報（会員ランクや、LTV、性別、Emailなど）をユーザープロフィールに登録できます。

このAPIを利用して更新したユーザープロフィールの情報を基にして、対象となるユーザーを絞り込んだプッシュ通知やメッセージを送信することができます。

これにより以下のような施策を実現できます。

- ゴールド会員ユーザー向けに特典情報を告知するプッシュ通知を送る
- LTVの高いロイヤルカスタマーのみに特設ページへ招待するメッセージを表示する

ユーザープロフィールに関する詳細は [ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md) をご覧ください。

##### NOTE
- ユーザープロフィールAPIでは、[標準ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md#standard-user-profile) を更新することはできません。

### はじめに

ユーザープロフィールAPIを使うには、Repro API トークンを利用する必要があります。



#### Repro API トークンの取得

1. **設定 > プロジェクト設定** に行き、 **認証情報 > Repro API トークン** を確認します。



##### WARNING
「APIトークンの再発行」をすると既存のAPIトークンを利用できなくなり、あとから復元することはできません。

### API 経由でユーザープロフィールを更新する

ユーザープロフィールAPIはHTTPの `POST` メソッドを受けつけるエンドポイントと紐付いています。

`POST https://api.reproio.com/v2/user_profiles`

#### 認証

取得した Repro API トークンをHTTPヘッダーの `X-Repro-Token` フィールドに設定してください。

#### 単位時間あたりのアクセス上限

ユーザープロフィールAPIには、単位時間当たりのアクセス制限があります。

- アクセス上限設定値は、APIトークンごとに1分あたり1000件です。
- リクエストが正常に完了すると、レスポンスの `X-RateLimit-Limit` ヘッダーに単位時間あたりのリクエスト上限回数が記載されます。
- リクエスト数がアクセス上限数を超えると、 `HTTP Status 429 (Too Many Requests)` が返ります。

レスポンスヘッダーの詳細は [ユーザープロフィールAPIのレスポンス](#user-profile-api-response) をご覧ください。

##### WARNING
- アクセス上限設定値は予告なく変動する場合があります。
- アクセス上限設定値は、機能単位でのAPIトークンごととなります。
   
  例えば、プッシュAPIとユーザープロフィールAPIは同じAPIトークンを利用していますが、別機能のため同時にリクエストしたとしても、それぞれ１件づつのカウントとなります。
   



#### APIフォーマット

メッセージをHTTP bodyにJSONフォーマットでセットします。

- `user_id`: アプリやWebサイト内で [ユーザーID](https://docs.repro.io/ja/dev/sdk/user-id.md) APIを使って登録されたユーザーのIDを指定します。
  - 登録されていないユーザーの場合は、 `HTTP Status 400 (Bad Request)` が返ります。詳細は [ユーザープロフィールAPIのレスポンス](#user-profile-api-response) をご覧ください。
- `user_profiles`: １つのペイロードで複数設定できます。（配列形式で格納します）
  - `key`: プロフィールのキーです。文字列のみが指定できます。nilや空文字列は不可、上限は255文字です。
  - `type`: プロフィールの型です。 `string` (文字列)、 `int` (整数)、 `decimal` (小数)、 `datetime` (日付) が指定できます。
  - `value`: プロフィールの値です。型に応じた値を指定します。

##### 文字列

セットできる文字数の上限は255文字です。

```json
{
  "key": "Job",
  "type": "string",
  "value": "Developer"
}
```

##### 整数

```json
{
  "key": "Age",
  "type": "int",
  "value": 25
}
```

##### 小数

```json
{
  "key": "Height",
  "type": "decimal",
  "value": 176.5
}
```

##### 日付

ISO8601 フォーマットに準拠した文字列のみセットできます。

```json
{
  "key": "LastLogin",
  "type": "datetime",
  "value": "2017-08-01T12:34:56.789+09:00"
}
```

#### ユーザープロフィールAPIのペイロード例

##### 1人のユーザーのプロフィールを更新する

```json
{
  "user_id": "user-123",
  "user_profiles": [
    {
      "key": "Job",
      "type": "string",
      "value": "Developer"
    },
    {
      "key": "Age",
      "type": "int",
      "value": 25
    }
  ]
}
```

##### NOTE
- 同じキーのプロフィールを複数指定した場合、一番最後のプロフィールが更新の対象となります。

##### WARNING
- 既に存在しているユーザープロフィールキーやデータ型は後から変更や削除をすることができません。詳しくは、 [ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md) をご覧ください。



### ユーザープロフィールAPIのリクエスト

**リクエストヘッダー**

リクエストのヘッダーには、以下の値を設定します。

| ヘッダー | 説明 | 必須 |
| --- | --- | --- |
| Content-Type | application/jsonを指定します。 | 必須 |
| X-Repro-Token | [Repro API トークンの取得](#user-profile-api-get-api-token) で取得したトークンを指定します。 | 必須 |

**リクエストボディ**

メッセージをJSONフォーマットで設定します。



### ユーザープロフィールAPIのレスポンス

**レスポンスヘッダー**

レスポンスのヘッダーには、以下の値が含まれます。

| ステータス | ヘッダー | 説明 |
| --- | --- | --- |
| 正常 | `X-RateLimit-Limit` | 単位時間あたりのアクセス上限 |
| 正常 | `X-RateLimit-Remaining` | アクセスできる残り回数 |
| 正常 | `X-RateLimit-Reset` | アクセス数がリセットされる時刻(unixtime) |
| リクエスト制限 | `Retry-After` | 再実行可能になるまでの秒数 |

**レスポンスボディ**

ユーザープロフィールAPIをコールした際の、レスポンスに含まれるステータスコードとエラーメッセージの一覧は下記になります。

#### 202 Accepted

リクエストが成功しました。更新したユーザーIDおよびプロフィールに関してはレスポンスボディをご確認ください。

レスポンスボディ:

```json
{
  "user_id": "user-123",
  "user_profiles": [
    {
      "key": "Job",
      "type": "string",
      "value": "Developer"
    },
    {
      "key": "Age",
      "type": "int",
      "value": 25
    },
    {
      "key": "LastLogin",
      "type": "datetime",
      "value": "2017-08-01 03:34:56.789"
    }
  ]
}
```

##### NOTE
- 日付型のプロフィールの値はサーバー側でUTCに変換されます。

#### 400 Bad Request

リクエストにエラーがあります。エラーメッセージを確認の上、対応してください。

##### 1001 ペイロードの形式に誤りがあります

`user_id` や `user_profiles` の形式をご確認ください。

レスポンスボディ:

```json
{
  "error": {
    "code": 1001,
    "messages": [
      "user_id is missing"
    ]
  }
}
```

##### 1002 ユーザーIDが登録されていません

指定したユーザーIDはまだアプリやWebサイトから登録されていません。

レスポンスボディ:

```json
{
  "error": {
    "code": 1002,
    "messages": [
      "'user-123' is not registered"
    ]
  }
}
```

##### 1003 ユーザープロフィールの key, type, value が適切に設定されていません

エラーメッセージに加えて、 [APIフォーマット](#user-profiles-payload) もご確認ください。

レスポンスボディ:

```json
{
  "error": {
    "code": 1003,
    "messages": [
      "Job does not have a valid value"
    ]
  }
}
```

##### WARNING
- １つでも適切に設定されていないプロフィールがあると同じペイロード内の全てのプロフィールが更新されません。

#### 401 Unauthorized

Repro API トークンが指定されていません。

レスポンスボディ:

```json
{
  "status": "unauthorized",
  "error": {
    "messages": [
      "Please include your Repro API Token as \"X-Repro-Token\" HTTP header."
    ]
  }
}
```

#### 403 Forbidden

指定した Repro API トークンが間違っています。

レスポンスボディ:

```json
{
  "status": "forbidden",
  "error": {
    "messages": [
      "Please check your Repro API Token as \"X-Repro-Token\" HTTP header."
    ]
  }
}
```

#### 404 Not Found

エンドポイントが存在しません。

レスポンスボディ:

```json
{
  "status": "not_found",
  "error": {
    "messages": [
      "Not found."
    ]
  }
}
```

#### 429 Too Many Requests

リクエスト数が多すぎます。 `Retry-After` ヘッダーに記載された秒数待った後、リクエストを再開してください。

レスポンスボディ:

```json
{
  "status": "too_many_requests",
  "error": {
      "messages": [
          "Too many requests hit the API too quickly."
      ]
  }
}
```

---

## オーディエンスAPI

オーディエンスAPIを使うと、任意の [ユーザーID](https://docs.repro.io/ja/dev/sdk/user-id.md) のリストを使ってオーディエンスを作成、もしくは更新することができます。

自社の分析基盤や、他社サービスなどで作成したユーザーIDのリストをReproに登録し、マーケティング施策の配信対象として利用することができます。

##### NOTE
- Reproに登録されているユーザーが対象となります。Reproに登録されていないユーザーが含まれている場合は、対象として計上されません。

### はじめに



#### Repro API トークンの確認

オーディエンスAPIを使うには、Repro API トークンを使用します。

1. **設定 > プロジェクト設定** に行き、 **認証情報 > Repro API トークン** を確認します。



##### WARNING
「APIトークンの再発行」をすると既存のAPIトークンを利用できなくなり、あとから復元することはできません。



### オーディエンスAPI v3

現在、オーディエンスAPI v3では下記の機能を提供しています。
データをアップロードするために異なるエンドポイントに対して 2 回リクエストを送る必要があります。なお、2回目のリクエストについては、新規作成と更新で全く同じです。

| 機能 | HTTPメソッド | エンドポイント |
| --- | --- | --- |
| 新規作成 | `POST` | `https://api.reproio.com/v3/audiences` |
| 更新 | `PUT` | `https://api.reproio.com/v3/audiences/<オーディエンスID>` |

以降では、リクエスト方法の詳細を記載していきます。

##### NOTE
pre-signed URLの有効期限は5分です。そのため、1回目のレスポンスを受け取ってから5分以内に2回目のリクエストを開始してください。

#### 単位時間あたりのアクセス上限

オーディエンスAPIには単位時間当たりのアクセス上限があります。

- アクセス上限設定値は、APIトークンごとに10分あたり15件です。
- リクエストが正常に完了すると、レスポンスの `X-RateLimit-Limit` ヘッダーに単位時間あたりのリクエスト上限回数が記載されます。
- リクエスト数がアクセス上限数を超えると、 `HTTP Status 429 (Too Many Requests)` が返ります。

レスポンスヘッダーの詳細 [レスポンスヘッダー](#response-header) をご覧ください。

##### WARNING
- アクセス上限設定値は予告なく変動する場合があります。
- アクセス上限設定値は、機能単位でのAPIトークンごととなります。
   
  例えば、プッシュAPIとユーザープロフィールAPIは同じAPIトークンを利用していますが、別機能のため同時にリクエストしたとしても、それぞれ１件づつのカウントとなります。
   



#### サンプルコード

オーディエンスの新規作成のサンプルコードを以下に記載します。
オーディエンスの更新用に変更するには以下2点を変更してください。

- 1回目のリクエストのエンドポイントを更新用のものに変更する
- 1回目のリクエストメソッドを POST から PUT に変更する

```sh
#!/bin/bash

set -e

API_TOKEN="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
AUDIENCES_URI=https://api.reproio.com/v3/audiences

file=$(realpath -e $1)
checksum=$(openssl dgst -md5 -binary ${file} | base64)
content_size=$(stat -c %s ${file})

body=$(cat <<EOF
{
  "name": "my-audience-api",
  "checksum":"${checksum}",
  "byte_size":"${content_size}"
}
EOF
)

# First request
response=$(curl -v -X POST \
                -H "X-Repro-Token: ${API_TOKEN}" \
                -H "Content-Type: application/json" \
                --data "${body}" \
                ${AUDIENCES_URI})
echo $response

# Get the value needed for the second request from the response
url=$(echo ${response} | jq -r .direct_upload.url)
content_type=$(echo ${response} | jq -r '.direct_upload.headers["Content-Type"]')
content_md5=$(echo ${response} | jq -r '.direct_upload.headers["Content-MD5"]')

# Second request
curl -X PUT \
    -H "Content-Type: ${content_type}" \
    -H "Content-MD5: ${content_md5}" \
    --upload-file ${file} \
    "${url}"

echo done
```

#### オーディエンスの新規作成

以下の2ステップを実行することで、オーディエンスの新規作成を行うことができます。

1. `POST /v3/audiences` を実行し、S3にダイレクトアップロードするためのpre-signed URLを取得する
2. `PUT <pre-signed URL>` を実行し、S3にファイルをアップロードする

##### 1回目のリクエスト

###### エンドポイント

| 機能 | HTTPメソッド | エンドポイント |
| --- | --- | --- |
| 新規作成 | `POST` | `https://api.reproio.com/v3/audiences` |

###### リクエストヘッダー

| ヘッダー | 説明 | 任意 / 必須 |
| --- | --- | --- |
| Content-Type | application/jsonを指定します。 | 必須 |
| X-Repro-Token | [Repro API トークンの確認](#repro-api-token) で取得したトークンを指定します。 | 必須 |

###### リクエストパラメータ

| フィールド | 説明 | 任意 / 必須 |
| --- | --- | --- |
| name | 作成するオーディエンスの名前。 | 必須 |
| checksum | ファイルのmd5 checksumをbase64エンコードしたもの。 `openssl dgst -md5 -binary hoge.csv | base64` で算出することができます。 | 必須 |
| byte_size | オーディエンスの作成・更新に利用するファイルのファイルサイズ | 必須 |

###### ペイロード例

```json
{
  "name": "audience name",
  "checksum": "J1h240z2CdsRjz2Et5mnkA==",
  "byte_size": "1024"
}
```



###### レスポンスヘッダー

レスポンスのヘッダーには、以下の値が含まれます。

| ステータス | ヘッダー | 説明 |
| --- | --- | --- |
| 正常 | `X-RateLimit-Limit` | 単位時間あたりのアクセス上限 |
| 正常 | `X-RateLimit-Remaining` | アクセスできる残り回数 |
| 正常 | `X-RateLimit-Reset` | アクセス数がリセットされる時刻(unixtime) |
| リクエスト制限 | `Retry-After` | 再実行可能になるまでの秒数 |

###### 正常系レスポンス

リクエスト成功時、レスポンスボディはJSON形式で以下の内容が返ってきます。

| フィールド | 説明 |
| --- | --- |
| response.id | オーディエンスのID |
| response.name | オーディエンスの名前 |
| response.direct_upload | 2回目のリクエストに必要な情報を格納したオブジェクト |
| response.direct_upload.url | 2回目のリクエストのエンドポイントURL |
| response.direct_upload.headers | 2回目のリクエストに必要なヘッダー情報 |

###### 正常系レスポンスボディ例

```json
{
  "id": "ym6nnpkd",
  "direct_upload": {
    "url": "https://repro-direct-upload-production.s3.ap-northeast-1.amazonaws.com/Sx9367LtCmGDRdqfUJVjirRv?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAITZGHBHURRYGMYHA%2F20200312%2Fap-northeast-1%2Fs3%2Faws4_request&X-Amz-Date=20200312T062037Z&X-Amz-Expires=300&X-Amz-SignedHeaders=content-md5%3Bcontent-type%3Bhost&X-Amz-Signature=ef75a6b81944375822bcd4c2cdabf362bd02ccce5850577917b6b3fe087de0c5",
    "headers": {
      "Content-Type": "text/csv",
      "Content-MD5": "J1h240z2CdsRjz2Et5mnkA=="
    }
  },
  "name": "my-audience-api"
}
```

###### エラーレスポンス

レスポンスに含まれるステータスコードとエラーメッセージの一覧は下記になります。

###### 400 Bad Request

リクエストにエラーがあります。エラーメッセージを確認の上、対応してください。

checksumに不正な文字列が含まれています。

レスポンスボディ:

```json
{
  "error": {
    "messages": [
      "Validation failed: Checksum is invalid"
    ]
  }
}
```

byte_sizeが指定されていません。

レスポンスボディ:

```json
{
  "error": {
    "messages": [
      "param is missing or the value is empty: byte_size"
    ]
  }
}
```

###### 401 Unauthorized

Repro API トークンが指定されていません。

レスポンスボディ:

```json
{
  "status": "unauthorized",
  "error": {
    "messages": [
      "Please include your Repro API Token as \"X-Repro-Token\" HTTP header."
    ]
  }
}
```

###### 403 Forbidden

指定した Repro API トークンが間違っています。

レスポンスボディ:

```json
{
  "status": "forbidden",
  "error": {
    "messages": [
      "Please check your Repro API Token as \"X-Repro-Token\" HTTP header."
    ]
  }
}
```

###### 404 Not Found

エンドポイントが存在しません。

レスポンスボディ:

```json
{
  "status": "not_found",
  "error": {
    "messages": [
      "Not found."
    ]
  }
}
```

###### 429 Too Many Requests

リクエスト数が多すぎます。 `Retry-After` ヘッダーに記載された秒数待った後、リクエストを再開してください。

レスポンスボディ:

```json
{
  "status": "too_many_requests",
  "error": {
    "messages": [
      "Too many requests hit the API too quickly."
    ]
  }
}
```

##### 2回目のリクエスト

###### エンドポイント

| HTTPメソッド | エンドポイント |
| --- | --- |
| `PUT` | 1回目のリクエストが成功した場合、レスポンスに含まれる `response.direct_upload.url` の値 |

###### リクエストヘッダー

1回目のリクエストが成功した場合、レスポンスに含まれる `response.direct_upload.headers` の値全てをヘッダーとして指定してください。

###### リクエストパラメータ

オーディエンスを作成するためのCSVファイルをセットしてください。
セット可能なファイルサイズの上限は500MBです。
ファイルの形式は、1行に1つのユーザーIDを指定した以下のようなCSVです。例えば `qwpeoifjadlskf`, `zxocjvasdfoiji`, `azxcpoqnadslpx` のようなユーザーIDを設定している場合、次のような形式のファイルになります。

```
qwpeoifjadlskf
zxocjvasdfoiji
azxcpoqnadslpx
:
```

###### 正常系レスポンス

オーディエンスの作成に成功したら、 `200` のステータスコードが返されます。

###### エラーレスポンス

エラーレスポンスについては [こちら](https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html) のドキュメントを参照してください。

##### インポート結果のメールを受信する

インポートが完了すると、下記のようなメールが送信されます。
URLにアクセスし、インポート結果を確認してください。



#### オーディエンスの更新

以下の2ステップを実行することで、オーディエンスの更新を行うことができます。

1. `PUT /v3/audiences/<オーディエンスID>` を実行し、S3にダイレクトアップロードするためのpre-signed URLを取得する
2. `PUT <pre-signed URL>` を実行し、S3にファイルをアップロードする

以降の手順は [サンプルコード](#create-audience) と同様になります。こちらを参照してください。
エンドポイントについては、以下管理画面上のオーディエンス詳細画面から確認することもできます。





### オーディエンスAPI v2(廃止)

##### WARNING
**オーディエンスAPI v2は2021年8月31日に廃止しました。** オーディエンスAPIをご利用する場合は [オーディエンスAPI v3](#audience-api-v3) をご利用ください。

---

## ReproへのLINEユーザーIDの登録 (Web SDK)

Reproでは、LINEのユーザーIDを登録することで、LINE経由でユーザーにメッセージを送信することができます。

##### WARNING
- LINEユーザーIDのみで登録することはできません。
- LINEユーザーIDは、LINEで登録されているユーザーの表示名や、[LINEでの友だち検索に利用するLINE ID](https://guide.line.me/ja/account-and-settings/account-and-profile/set-line-id.html) とは異なります。
- LINEユーザーIDを登録する前に、事前に [LINEチャネルを作成](https://docs.repro.io/ja/dashboard/setting/line-channel-setting.md) してください。
- LINEユーザーIDを登録する前に、必ず `setUserID()` を使用してユーザーの識別子を設定してください。ユーザーIDが設定されていない状態では、LINEユーザーIDの登録は失敗します。

### LINEユーザーIDの登録

LINEのユーザーIDとチャネルIDをReproに登録するには、 `linkLineID` メソッドを使用します。LINE_USER_IDにはUから始まる33文字のLINEユーザーIDを、LINE_CHANNEL_IDには [LINEチャネル設定](https://docs.repro.io/ja/dashboard/setting/line-channel-setting.md) で作成したチャネルIDを設定してください。

```javascript
// Set user ID first
reproio('setUserID', 'user123');

// Link LINE User ID
reproio('linkLineID', 'LINE_USER_ID', 'LINE_CHANNEL_ID');
```

### LINEユーザーIDの登録解除

LINEユーザーIDの登録を解除するには、 `unlinkLineID` メソッドを使用します。LINE_USER_IDにはUから始まる33文字のLINEユーザーIDを、LINE_CHANNEL_IDには [LINEチャネル設定](https://docs.repro.io/ja/dashboard/setting/line-channel-setting.md) で作成したチャネルIDを設定してください。

```javascript
reproio('unlinkLineID', 'LINE_USER_ID', 'LINE_CHANNEL_ID');
```

### Notes

- LINEユーザーIDを登録する前に、必ず `setUserID()` でユーザーIDを設定してください。
- LINEユーザーIDとチャネルIDは空文字列やnullを指定できません。
- 登録に失敗した場合は、ユーザーIDが設定されているか確認してください。

---

## 検証方法

* [セットアップ](https://docs.repro.io/ja/dev/sdk/tests/setup.md)
* [ユーザーID](https://docs.repro.io/ja/dev/sdk/tests/user_id.md)
  * [1. IDEのログを確認](https://docs.repro.io/ja/dev/sdk/tests/user_id.md#ide)
  * [2. オーディエンスに追加出来るかを確認](https://docs.repro.io/ja/dev/sdk/tests/user_id.md#id1)
* [ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/tests/user_profile.md)
  * [1. IDEのログを確認](https://docs.repro.io/ja/dev/sdk/tests/user_profile.md#ide)
  * [2. 管理画面のユーザープロフィール設定から確認](https://docs.repro.io/ja/dev/sdk/tests/user_profile.md#id2)
  * [3. オーディエンス機能を利用して確認](https://docs.repro.io/ja/dev/sdk/tests/user_profile.md#id3)
* [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tests/events.md)
* [アプリ内メッセージ](https://docs.repro.io/ja/dev/sdk/tests/inapp.md)
* [プッシュ通知](https://docs.repro.io/ja/dev/sdk/tests/push.md)

---

## セットアップ

1. セットアップ完了前は、以下のような画面がダッシュボード上に表示されます。


1. [ログレベルをDebug](https://docs.repro.io/ja/dev/sdk/log.md) にして、お使いのIDE上でログが確認できる状態で、Repro SDK実装済みのアプリを使用した際に、下記のようなログが出力されることを確認してください。

- iOS

```
INFO : Repro Setup v5.23.0
...
DEBUG: Repro Successfully uploaded file: 'log_20260101123456789.json.deflate' (will delete)
```

- Android

```
I  Repro Setup v5.22.0
...
D  Successfully uploaded file: 'log_20260101123456789.json.deflate' (will delete)
```

##### NOTE
- SDKが収集した情報は定期的にサーバーにアップロードされます。
- 詳しくは、[セッション・ライフサイクル](https://docs.repro.io/ja/dev/sdk/session.md) をご参照ください。

##### NOTE
データの送信ができていない場合は、[セッションがアップロードされないケースは何がありますか？](https://docs.repro.io/ja/faq/app/sdk/2.md) をご確認ください。

1. 上記２の完了後、以下のような画面にダッシュボードが切り替わることを確認してください。

---

## ユーザーID

確認方法は2通りあります。

### 1. IDEのログを確認

[ログレベルをDebug](https://docs.repro.io/ja/dev/sdk/log.md) にして、正常にユーザーIDが設定されていた場合、IDEのコンソールに下記のようなログが出力されます。(以下では1234-5678をユーザーIDに設定しています)

- iOS

```
INFO : Repro Set User ID: 1234-5678
```

- Android

```
I  Set user ID: 1234-5678
```

### 2. オーディエンスに追加出来るかを確認

サイドメニューの[マーケティング] > [オーディエンス]にて[新規作成]からID指定を選択し、設定したユーザーIDを検索します。



正常にユーザーIDが設定されていれば、下記のように端末をオーディエンスに追加することが可能です。

---

## ユーザープロフィール

確認方法は3通りあります。

### 1. IDEのログを確認

[ログレベルをDebug](https://docs.repro.io/ja/dev/sdk/log.md) にして、正常にユーザープロフィールが設定されていた場合、IDEのコンソールに下記のようなログが出力されます。（以下では文字列のカスタムユーザープロフィールJobに対してDeveloperという値を設定しています）

- iOS

```
DEBUG: Repro Set user profile: Job = Developer
```

- Android

```
D  Set user profile: Job = Developer(string)
```

### 2. 管理画面のユーザープロフィール設定から確認

サイドメニューの[ユーザープロフィール] > [ユーザプロフィール設定]から設定されているユーザープロフィールの一覧を確認できます。



### 3. オーディエンス機能を利用して確認

[オーディエンス](https://docs.repro.io/ja/dashboard/campaign/audience.md) の手順に従い、オーディエンスに追加することでそのユーザーに紐づくユーザープロフィールを確認することができます。詳しくは、 [新規作成: ID指定](https://docs.repro.io/ja/dashboard/campaign/audience.md#create-specified-id) をご確認ください。

---

## イベントトラッキング

1. サイドメニューの[イベント] > [イベント設定]からトラッキングされたイベント一覧を確認することができます。


1. 上記にイベントが追加されない場合は、以下のドキュメントに従って、イベントが正しく送信されているかを確認してください。

- [イベントが上がってきません。何が原因ですか？](https://docs.repro.io/ja/faq/app/event-tracking/1.md)

---

## イベントが上がってきません。何が原因ですか？

イベントやユーザープロフィールなどのデータは、定期的に送信されます。

管理画面上でイベントが実行されたことを確認するためには、オーディエンスから [QRコードを利用してユーザーを追加する](https://docs.repro.io/ja/dashboard/campaign/audience.md#add-user) をしてください。
その後、 [ユーザーの詳細画面](https://docs.repro.io/ja/dashboard/campaign/audience.md#users-show) で対象イベントの実行回数が表示されることを確認してください。

また、イベントトラッキングが正しく実装されている場合は、下記のようなデバッグログがイベントを実行したタイミングでアプリの開発環境（Xcode、Android Studio）のコンソール上に表示されますので併せてご確認下さい。
なお、[ログレベル](https://docs.repro.io/ja/dev/sdk/log.md) を DEBUG にする必要があります。

- **標準イベント**

```
Track standard event name=view_content properties={
  "value": 5000,
  "currency": "JPY",
  "content_category": "Clothing & Shoes > Mens > Clothing",
  "content_name": "Slim Jeans",
  "content_id": "1234"
}
```

- **カスタムイベント**

```
Track custom event name=user review properties={
    "rating": 3
}
```

---

## アプリ内メッセージ

1. 管理画面からメッセージを選択し、キャンペーンを新規作成してください。
2. 新規キャンペーン作成画面下部の「配信対象設定」からオーディエンスをフィルターに選択してください。
3. オーディエンス対象の検証用端末で、意図した通りにアプリ内メッセージが表示されることを確認してください。

##### WARNING
表示されない場合はイベントの実行タイミングが正しくない場合があります。
その場合は [こちら](https://docs.repro.io/ja/dev/sdk/in-app-message.md) を参照し、イベントの実行タイミングを変更するか表示トリガーイベントを変更してください。

---

## プッシュ通知

以下のドキュメントを参考にして、プッシュ通知機能の検証を行ってください。
: - [プッシュ通知が受信できないのですが、原因は何かありますか？](https://docs.repro.io/ja/faq/app/push/1.md)

---

## プッシュ通知が受信できないのですが、原因は何かありますか？

以下のフローに則りご確認ください。
プッシュAPIで配信できなかった場合も同様のフローをお試しください。

### 1.アプリを起動してセッションデータをアップロードする

アプリを起動後、セッション情報は定期的にアップロードされます。

### 2.検証端末をオーディエンスに設定する

検証端末に設定されているユーザーを含んだ [オーディエンス](https://docs.repro.io/ja/dashboard/campaign/audience.md) を作成してください。

#### ユーザーが見つからない場合

[ユーザーが見つからない場合](https://docs.repro.io/ja/dashboard/campaign/audience.md#tester-not-found) を参照ください。
セッションデータがReproに上がっていない場合は、プッシュ通知を配信することが出来ません。

### 3.プッシュ通知をオーディエンス配信する

新しいプッシュ通知を作成し、配信条件を **オーディエンス** にして、先程登録したオーディエンスを設定して配信をしてください。

#### プッシュ通知が受信できた場合

検証端末が配信条件に含まれないため、プッシュ通知が受信できなかったと考えられます。
検証端末が配信条件を満たしているかご確認ください。

確認方法：

- イベント、イベントプロパティ： [イベントが上がってきません。何が原因ですか？](https://docs.repro.io/ja/faq/app/event-tracking/1.md)
- ユーザープロフィール： [ユーザープロフィールが登録されているか確認したい](https://docs.repro.io/ja/faq/app/user-profile/2.md)

プッシュAPIで受信できず、オーディエンス配信は受信できた場合は、以下をご確認ください。

- プッシュAPIのリクエストが失敗している
- プッシュAPIのリクエストペイロードに対象のユーザーIDが含まれていない
- [Android]カスタムJSON形式の場合、 [カスタムJSON用のReceiver](https://docs.repro.io/ja/dev/sdk/push-notification/android.md#customize-receiver) が実装されていない。または実装が正しくない

#### プッシュ通知が受信できない場合

次のフローにお進みください。

##### WARNING
次のオーディエンスの項目を確認するまで、アプリを起動しないようにしてください。Reproにセッション情報をアップロードすると状態が変わってしまい、正しい判別が出来なくなる可能性があります。

### 4.オーディエンスの項目を確認する

オーディエンスで検証端末について、 [ユーザーの情報](https://docs.repro.io/ja/dashboard/campaign/audience.md#users-info) をご確認ください。

#### プッシュトークンが存在しない場合

プッシュトークンを取得する実装に問題がないかご確認ください。

#### プッシュトークン利用可否が×の場合

プッシュ用証明書が間違っている可能性があります。
**設定 > プッシュ通知設定** 画面に設定されている証明書について以下をご確認ください。

- [iOS] 証明書が開発用だが、ストアからインストールした本番用アプリで検証している
- [iOS] 証明書が本番用だが、開発環境からビルドした開発用アプリで検証している
- [iOS] 証明書の証明書名(Bundle ID)がアプリのBundle IDが一致していない
- [Android] 登録されているFCM Server Keyが、アプリ内部のgoogle-services.jsonと対応していない

##### NOTE
iOSの証明書は **設定 > プッシュ通知設定** の **プラットフォーム** が以下のように表示されます。

- 本番用: APNS
- 開発用: APNS_SANDBOX

#### プッシュ通知許諾が×の場合

設定からプッシュ通知許諾をONにしてください。

#### 上記に当てはまらない場合

以下のいずれかの項目に該当する場合、プッシュ通知を表示できません。

- [iOS] **設定 > プッシュ通知設定** 画面に設定されている証明書の有効期限が切れている
- [Android]Android 8.0以上の場合、 [通知チャンネルの設定](https://docs.repro.io/ja/dev/sdk/push-notification/android.md#notification-channel-setting) が出来ていない
- [Android]Reproのプッシュ表示用の [Receiver](https://docs.repro.io/ja/dev/sdk/push-notification/android.md#register-receiver) が登録されていない
- [Android]カスタムJSON形式の場合、 [カスタムJSON用のReceiver](https://docs.repro.io/ja/dev/sdk/push-notification/android.md#customize-receiver) が実装されていない。または実装が正しくない
- 端末の電波状態、電力状態、ネットワーク状態が原因でプッシュ通知が受信できない状態になっている

---

## ユーザープロフィールが登録されているか確認したい

確認したい端末を [オーディエンス](https://docs.repro.io/ja/dashboard/campaign/audience.md) でID指定して設定してください。
その後、 [ユーザーの詳細画面](https://docs.repro.io/ja/dashboard/campaign/audience.md#users-show) で対象ユーザープロフィールが表示されることを確認してください。

もしくは、開発環境（AndroidStudioやXcode）でユーザープロフィールを登録したタイミングのログをご確認いただくことで、登録処理が実行されているか確認できます。
なお、 [ログレベル](https://docs.repro.io/ja/dev/sdk/log.md) を DEBUG にする必要があります。

### ユーザープロフィール設定時

以下のユーザープロフィールを設定した場合、設定したタイミングでログが出力されます。

- ユーザーID：test
- ユーザープロフィール名：Age(Int型)
- ユーザープロフィールの値：25

#### iOS

```
DEBUG: Repro User profile for this session(id=test): (
      {
        name = Age;
        type = int;
        value = 25;
    },
)
```

#### Android

```
D/Repro: Set user profile: Age = 25(int)
```

---

## Web

* [導入](https://docs.repro.io/ja/dev/web/getstarted/web.md)
  * [Repro Webを導入する](https://docs.repro.io/ja/dev/web/getstarted/web.md#repro-web)
  * [アカウントにログインする](https://docs.repro.io/ja/dev/web/getstarted/web.md#setting-login-for-repro)
  * [導入方法を選択する](https://docs.repro.io/ja/dev/web/getstarted/web.md#choose-deployment-method)
  * [Google Tag Manager(GTM)で導入する](https://docs.repro.io/ja/dev/web/getstarted/web.md#google-tag-manager-gtm)
  * [セットアップ計測タグを導入する](https://docs.repro.io/ja/dev/web/getstarted/web.md#install-setup-measurement-tags)
  * [コンバージョン計測タグを導入する](https://docs.repro.io/ja/dev/web/getstarted/web.md#install-cv-measurement-tags)
  * [イベント計測タグを導入する](https://docs.repro.io/ja/dev/web/getstarted/web.md#install-event-measurement-tags)
  * [ユーザープロフィールを取得する](https://docs.repro.io/ja/dev/web/getstarted/web.md#get-user-profile)
  * [Webページに直接タグを埋め込み導入する](https://docs.repro.io/ja/dev/web/getstarted/web.md#web)
  * [セットアップ計測タグを導入する](https://docs.repro.io/ja/dev/web/getstarted/web.md#install-setup-measurement-tags-2)
  * [コンバージョン計測タグの導入](https://docs.repro.io/ja/dev/web/getstarted/web.md#install-cv-measurement-tags-2)
  * [イベント計測タグの導入](https://docs.repro.io/ja/dev/web/getstarted/web.md#install-event-measurement-tags-2)
  * [ユーザープロフィールを取得する](https://docs.repro.io/ja/dev/web/getstarted/web.md#get-user-profile-2)
  * [最後に](https://docs.repro.io/ja/dev/web/getstarted/web.md#id44)
* [ユーザーID](https://docs.repro.io/ja/dev/web/user-id.md)
  * [ユーザーIDをセットする](https://docs.repro.io/ja/dev/web/user-id.md#id1)
* [ユーザープロフィール](https://docs.repro.io/ja/dev/web/user-profile.md)
  * [標準ユーザープロフィール](https://docs.repro.io/ja/dev/web/user-profile.md#web-standard-user-profile)
  * [自動でセットされる標準ユーザープロフィール](https://docs.repro.io/ja/dev/web/user-profile.md#id7)
  * [カスタムユーザープロフィール](https://docs.repro.io/ja/dev/web/user-profile.md#web-custom-profile)
  * [条件付きセット操作](https://docs.repro.io/ja/dev/web/user-profile.md#web-user-profile-conditional-set)
  * [増減操作](https://docs.repro.io/ja/dev/web/user-profile.md#web-user-profile-increment-and-decrement)
  * [標準ユーザープロフィールの条件付きセット・増減操作](https://docs.repro.io/ja/dev/web/user-profile.md#id26)
  * [ユーザープロフィールの削除](https://docs.repro.io/ja/dev/web/user-profile.md#id34)
* [ReproへのLINEユーザーIDの登録 (Web SDK)](https://docs.repro.io/ja/dev/web/line-integration.md)
  * [LINEユーザーIDの登録](https://docs.repro.io/ja/dev/web/line-integration.md#lineid)
  * [LINEユーザーIDの登録解除](https://docs.repro.io/ja/dev/web/line-integration.md#id1)
  * [Notes](https://docs.repro.io/ja/dev/web/line-integration.md#notes)
* [イベントトラッキング](https://docs.repro.io/ja/dev/web/tracking.md)
  * [標準イベント](https://docs.repro.io/ja/dev/web/tracking.md#web-standard-event)
  * [カスタムイベント](https://docs.repro.io/ja/dev/web/tracking.md#web-custom-event)
  * [管理画面からイベントを設定する](https://docs.repro.io/ja/dev/web/tracking.md#id15)
* [セッション・ライフサイクル](https://docs.repro.io/ja/dev/web/session.md)
  * [Web](https://docs.repro.io/ja/dev/web/session.md#web)
* [デバイスID](https://docs.repro.io/ja/dev/web/device-id.md)
  * [デバイスIDを取得](https://docs.repro.io/ja/dev/web/device-id.md#get-web-divice-id)
* [オプトアウト機能](https://docs.repro.io/ja/dev/web/optout.md)
  * [オプトインの初期状態の指定](https://docs.repro.io/ja/dev/web/optout.md#id2)
  * [オプトインの指定](https://docs.repro.io/ja/dev/web/optout.md#id3)
  * [オプトアウトの指定](https://docs.repro.io/ja/dev/web/optout.md#id4)
  * [オプトイン/オプトアウトの状態を確認する](https://docs.repro.io/ja/dev/web/optout.md#id5)
* [バージョン1 から バージョン2 への更新手順](https://docs.repro.io/ja/dev/web/migration.md)
  * [導入スニペットの変更](https://docs.repro.io/ja/dev/web/migration.md#id2)
  * [ユーザーIDの変更](https://docs.repro.io/ja/dev/web/migration.md#id)
  * [イベントの設定](https://docs.repro.io/ja/dev/web/migration.md#id3)
  * [ユーザープロフィールの設定](https://docs.repro.io/ja/dev/web/migration.md#id4)
* [API](https://docs.repro.io/ja/dev/web/api.md)
  * [Setup / ユーザーID](https://docs.repro.io/ja/dev/web/api.md#setup-id)
  * [イベントトラッキング](https://docs.repro.io/ja/dev/web/api.md#id1)
  * [ユーザープロフィール](https://docs.repro.io/ja/dev/web/api.md#id2)
  * [デバイスID](https://docs.repro.io/ja/dev/web/api.md#id)
  * [オプトアウト機能](https://docs.repro.io/ja/dev/web/api.md#id3)
  * [クロスドメイン・トラッキング機能](https://docs.repro.io/ja/dev/web/api.md#id4)
  * [LINEユーザーIDの連携](https://docs.repro.io/ja/dev/web/api.md#lineid)
  * [その他](https://docs.repro.io/ja/dev/web/api.md#id5)
* [クロスドメイン・トラッキング機能](https://docs.repro.io/ja/dev/web/cross-domain-tracking.md)
  * [クロスドメイン・トラッキングが可能なケース](https://docs.repro.io/ja/dev/web/cross-domain-tracking.md#id2)
  * [クロスドメイン・トラッキングが不可能なケース](https://docs.repro.io/ja/dev/web/cross-domain-tracking.md#id3)
  * [設定時の注意事項](https://docs.repro.io/ja/dev/web/cross-domain-tracking.md#id4)
  * [注意すべきケース](https://docs.repro.io/ja/dev/web/cross-domain-tracking.md#id5)
  * [設定時の注意事項](https://docs.repro.io/ja/dev/web/cross-domain-tracking.md#id6)
* [WebViewでの動作について](https://docs.repro.io/ja/dev/web/webview.md)
  * [Web SDK側の設定](https://docs.repro.io/ja/dev/web/webview.md#web-sdk)
  * [アプリ側の実装 - 必要な設定](https://docs.repro.io/ja/dev/web/webview.md#id1)
* [SPA(Single Page Application)サイトへの導入](https://docs.repro.io/ja/dev/web/spa.md)
  * [SPAサイトへ導入する](https://docs.repro.io/ja/dev/web/spa.md#spa)
  * [SPAモードで変わること](https://docs.repro.io/ja/dev/web/spa.md#id2)
  * [SPAで構成されていないWebサイトでSPAモードをオンにする](https://docs.repro.io/ja/dev/web/spa.md#spawebspa)
  * [SPAサイトでユーザーIDをセットする](https://docs.repro.io/ja/dev/web/spa.md#spaid)
* [Webプッシュ通知](https://docs.repro.io/ja/dev/web/web-push-notification.md)
  * [ServiceWorkerファイルのダウンロードとホスティング](https://docs.repro.io/ja/dev/web/web-push-notification.md#serviceworker)
  * [ServiceWorkerのホスト先の指定](https://docs.repro.io/ja/dev/web/web-push-notification.md#id1)
  * [manifestファイルの作成とホスティング（iOS用）](https://docs.repro.io/ja/dev/web/web-push-notification.md#manifest-ios)
  * [通知許諾を表示する](https://docs.repro.io/ja/dev/web/web-push-notification.md#id2)
  * [Webプッシュ通知が利用可能であることを確認する](https://docs.repro.io/ja/dev/web/web-push-notification.md#id3)
* [Repro Webの計測タグが正しく動いているか確認する](https://docs.repro.io/ja/dev/web/measurement-tag.md)
  * [計測タグが正しく設置されているかを確認する](https://docs.repro.io/ja/dev/web/measurement-tag.md#measurement-tag-1)
  * [計測タグが正しく動作しているかを確認する](https://docs.repro.io/ja/dev/web/measurement-tag.md#measurement-tag-2)
  * [計測タグが正しく通信できているかを確認する](https://docs.repro.io/ja/dev/web/measurement-tag.md#measurement-tag-3)
  * [イベントトラッキングが正しく動作しているかを確認する](https://docs.repro.io/ja/dev/web/measurement-tag.md#measurement-tag-4)
* [Repro Webの利用するCookieについて](https://docs.repro.io/ja/dev/web/cookies.md)

---

## ユーザープロフィール

ユーザープロフィールは、性別、年齢、地域、言語、会員種別など、Webサイト内で収集可能なユーザーの付帯情報です。

このプロフィール情報を基にして、対象となるユーザーを絞り込んでメッセージを送信することができるようになります。

それぞれのプロフィール情報は固有のユーザーIDにひもづけられます。
プロフィール情報をセットする前に、 [ユーザーIDをセットする](https://docs.repro.io/ja/dev/web/user-id.md) ことをおすすめします。ユーザーIDがセットされていない場合は、匿名ユーザーの情報として扱われ、Reproが任意に設定したIDにひもづけられます。
匿名のユーザーIDの更新は、ブラウザのストレージが更新されるタイミングで更新されます。

##### WARNING
- 一度登録したユーザープロフィールキーやデータ型は、後から変更や削除をすることができません。
- ユーザープロフィール設定数に上限はありません。 但し、アナリティクスでの [フィルター](https://docs.repro.io/ja/dashboard/analytics/filter.md) や、キャンペーン機能で [ユーザープロフィールでフィルタリング](https://docs.repro.io/ja/dashboard/campaign/audience.md#audience-user-profile-filtering) する際には利用に上限があります。 現在の設定数は **設定 > ユーザープロフィール設定** で確認することができます。
- **ユーザープロフィール設定** では、プッシュ通知やメッセージなど、キャンペーン機能の対象者を絞り込むために利用できるユーザープロフィールの設定を変更することができます。ここで無効にしたユーザープロフィールは、キャンペーン作成画面やアナリティクス画面のユーザー情報による絞り込みの候補として表示されません。
- キャンペーン機能の対象者の絞り込みに利用できる上限を超えてユーザープロフィールを設定した場合は、ユーザープロフィールとして設定はされますがキャンペーン機能の絞り込みの候補としては表示されません。
- **ユーザープロフィール設定** でキャンペーン対象者の絞り込みに利用されているユーザープロフィールを無効にすると、該当するキャンペーンは配信されなくなります。



### 標準ユーザープロフィール

Reproではユーザーを絞り込む上で典型的なプロフィールを **標準ユーザープロフィール** として定義しています。 **標準ユーザープロフィール** をセットする際は、情報の種類に応じたAPIを呼び出してください。また、Webサイト独自のユーザープロフィールをセットする際は [カスタムユーザープロフィール](#web-custom-profile) をご利用ください。

#### 性別

ユーザーの性別をセットします。指定できる性別はReproの定数として定義されています。

```js-web
// set the gender as "male"
reproio("setUserGender", "male");
// set the gender as "female"
reproio("setUserGender", "female");
// set the gender as "other"
reproio("setUserGender", "other");
```

メッセージのフィルターを設定する際は、以下の表を参照し、文字列で指定してください。

| 性別 | フィルターに指定する値 |
| --- | --- |
| 男性 | male |
| 女性 | female |
| その他 | other |

#### 年齢

ユーザーの年齢を整数でセットします。

```js-web
// set the age as 20
reproio('setUserAge', 20);
```

#### 生年月日

ユーザーの生年月日をセットします。

```js-web
// set the date of birth as January 1, 2000
var dateOfBirth = new Date('2000-01-01');
reproio('setUserDateOfBirth', dateOfBirth);
```

#### 都道府県

ユーザーが住んでいる都道府県をセットします。

```js-web
// set the residence prefecture as "北海道"
reproio("setUserResidencePrefecture", "北海道");
...
// set the residence prefecture as "沖縄県"
reproio("setUserResidencePrefecture", "沖縄県");
```

指定出来る文字列は、下記に記載する47都道府県の `都` `道` `府`
`県` まで含めた文字列です。

| 都道府県として設定できる文字列 |
| --- |
| 北海道、青森県、岩手県、宮城県、秋田県、山形県、福島県、茨城県、栃木県、群馬県、埼玉県、 千葉県、東京都、神奈川県、新潟県、富山県、石川県、福井県、山梨県、長野県、岐阜県、静岡県、 愛知県、三重県、滋賀県、京都府、大阪府、兵庫県、奈良県、和歌山県、鳥取県、島根県、岡山県、 広島県、山口県、徳島県、香川県、愛媛県、高知県、福岡県、佐賀県、長崎県、熊本県、大分県、 宮崎県、鹿児島県、沖縄県 |

#### Eメールアドレス

ユーザーのEメールアドレスをセットします。

```js-web
reproio("setUserEmailAddress", "user@example.com");
```

### 自動でセットされる標準ユーザープロフィール

以下の標準ユーザープロフィールは、セッションが発生するたびに自動でセットされるため、APIを呼び出す必要はありません。

#### 最後に使った日

ユーザーが最後にWebサイトを利用した日付がセットされます。

#### ロケール

ユーザーの端末に設定されているロケールが文字列としてセットされます。IETF言語タグの書式に則り、 `language-script-region` のフォーマットで値がセットされます。IETF言語タグについては [こちらの記事](https://ja.wikipedia.org/wiki/IETF言語タグ) を参考にしてください。

##### NOTE
- 端末ロケールの値は機種に依存するため、同じロケールでも値は複数の可能性があります。例えば、同じ日本語ロケールでも値が `ja` と `ja-JP` のパターンがあります。
- そのため、配信フィルターで設定する際は、 `含む` 条件を利用してください。例えば、前述のように日本語ロケールを指定する場合は、「 `ja` を `含む` 」で配信フィルターを設定してください。

##### NOTE
- Safari 9(iOS)では自動収集されません

#### ランダムバケットID

ユーザーをランダムかつ均一に分布させたセグメントを作成できるユーザー属性情報です。セグメントに利用することでReproツールの導入検証を容易に行うことができます。
Repro上でユーザーが同定されたタイミングで一度だけランダムに生成され、以降変更されることはありません。値の範囲は0から9999までの整数です。
詳しくは [こちらの記事](https://support.repro.io/hc/ja/articles/53138250139929) を参考にしてください。

ユーザー同定については [ユーザーの定義](https://docs.repro.io/ja/dashboard/misc/user-definition.md) をご確認ください。

#### タイムゾーン

ユーザーの端末に設定されているタイムゾーンが文字列としてセットされます。設定される文字列は、Time Zone Databaseの命名規則に従います。例えば、日本標準時（JST）の場合は `Asia/Tokyo` でセットされます。Time Zone Databaseについては [こちらの記事](https://ja.wikipedia.org/wiki/Tz_database) を参考にしてください。

##### NOTE
- Safari 9(iOS)では自動収集されません



### カスタムユーザープロフィール

標準ユーザープロフィールとして定義されているもの以外の、サービス独自のプロフィールをセットします。プロフィールのキーには文字列のみが指定できます。 `___repro___` から始まるキーは指定できません。nullや空文字列は不可、上限は255文字です。

またプロフィールの値には、文字列、整数、小数、日付を指定できます。



#### 文字列

セットできる文字数の上限は255文字です。

```js-web
reproio("setStringUserProfile", "Job", "Developer");
```



#### 整数

```js-web
reproio("setIntUserProfile", "Age", 25);
```



#### 小数

```js-web
reproio("setDoubleUserProfile", "Height", 176.5);
```



#### 日付

```js-web
var now = new Date();
reproio("setDateUserProfile", "LastLogin", now);
```



### 条件付きセット操作

既にプロフィールが設定されている場合は更新せず、未設定の場合のみ値をセットします。

#### 文字列（条件付き）

指定したキーにプロフィールが未設定の場合のみ、文字列をセットします。

```js-web
reproio("onlySetIfAbsentStringUserProfile", "Job", "Developer");
```

#### 整数（条件付き）

指定したキーにプロフィールが未設定の場合のみ、整数をセットします。

```js-web
reproio("onlySetIfAbsentIntUserProfile", "LoginCount", 1);
```

#### 小数（条件付き）

指定したキーにプロフィールが未設定の場合のみ、小数をセットします。

```js-web
reproio("onlySetIfAbsentDoubleUserProfile", "Score", 85.5);
```

#### 日付（条件付き）

指定したキーにプロフィールが未設定の場合のみ、日付をセットします。

```js-web
reproio("onlySetIfAbsentDateUserProfile", "FirstLogin", new Date());
```



### 増減操作

既存の数値プロフィールに対して加算・減算を行います。プロフィールが未設定の場合は初期値を0として計算されます。

#### 整数の増加

指定したキーの整数プロフィールに値を加算します。

```js-web
reproio("incrementIntUserProfileBy", "LoginCount", 1);
```

#### 整数の減少

指定したキーの整数プロフィールから値を減算します。

```js-web
reproio("decrementIntUserProfileBy", "Credits", 10);
```

#### 小数の増加

指定したキーの小数プロフィールに値を加算します。

```js-web
reproio("incrementDoubleUserProfileBy", "Score", 5.5);
```

#### 小数の減少

指定したキーの小数プロフィールから値を減算します。

```js-web
reproio("decrementDoubleUserProfileBy", "Balance", 25.0);
```

### 標準ユーザープロフィールの条件付きセット・増減操作

標準ユーザープロフィールに対しても条件付きセットや増減操作が利用できます。

#### 年齢（条件付き）

年齢が未設定の場合のみ値をセットします。

```js-web
reproio("onlySetIfAbsentUserAge", 25);
```

#### 性別（条件付き）

性別が未設定の場合のみ値をセットします。

```js-web
reproio("onlySetIfAbsentUserGender", "male");
```

#### Eメールアドレス（条件付き）

Eメールアドレスが未設定の場合のみ値をセットします。

```js-web
reproio("onlySetIfAbsentUserEmailAddress", "user@example.com");
```

#### 居住都道府県（条件付き）

居住都道府県が未設定の場合のみ値をセットします。

```js-web
reproio("onlySetIfAbsentUserResidencePrefecture", "東京都");
```

#### 生年月日（条件付き）

生年月日が未設定の場合のみ値をセットします。

```js-web
reproio("onlySetIfAbsentUserDateOfBirth", new Date("1990-01-01"));
```

#### 年齢の増加

現在の年齢に指定した値を加算します。

```js-web
reproio("incrementUserAgeBy", 1);
```

#### 年齢の減少

現在の年齢から指定した値を減算します。

```js-web
reproio("decrementUserAgeBy", 1);
```

### ユーザープロフィールの削除

設定済みのユーザープロフィールを削除します。

#### カスタムプロフィールの削除

指定したキーのカスタムユーザープロフィールを削除します。

```js-web
reproio("deleteUserProfile", "Job");
```

#### 標準プロフィールの削除

標準ユーザープロフィールを削除します。

性別の削除:

```js-web
reproio("deleteUserGender");
```

年齢の削除:

```js-web
reproio("deleteUserAge");
```

Eメールアドレスの削除:

```js-web
reproio("deleteUserEmailAddress");
```

居住都道府県の削除:

```js-web
reproio("deleteUserResidencePrefecture");
```

生年月日の削除:

```js-web
reproio("deleteUserDateOfBirth");
```

---

## イベントトラッキング

Webサイトにおけるユーザーの行動をトラックできます。例えば以下のようなものがあげられます。

- ページの閲覧
- カートに追加
- 商品の購入
- ソーシャル・ネットワークへシェア

トラックされたイベントは分析機能のローデータとして使われます。また、メッセージを作成する際に、対象ユーザーをセグメントする条件としても利用できます。
イベントには付帯情報としてプロパティを指定できます。1つのイベントには最大20個のプロパティを指定可能です。

##### WARNING
- イベント設定数の上限はお客様のReproの契約プランによって異なります。無料プランの上限数はデフォルトで50件、有料プランの場合はデフォルトで200件です。
- イベント名を自動生成した場合、組み合わせが増えてすぐに上限に達しますので、ご注意ください。なお、現在のイベント設定数は **設定 > イベント設定** で確認することができます。

##### NOTE
- プロパティー名はnullや空文字列は不可、上限は48文字です。
- プロパティの値には文字列、または数値をセットできます。
- プロパティの値が文字列の場合は上限191文字です。

**すべてのイベントに次のようにプロパティが自動で追加されます**

例えば、URLが次の場合に自動で付与されるプロパティの例:
 
e.g. [http://docs.repro.io/ja/dev/web/tracking.html?highlight=tracking#web-standard-event](http://docs.repro.io/ja/dev/web/tracking.html?highlight=tracking#web-standard-event)
 

| 名称 | 説明 | 例 |
| --- | --- | --- |
| url | URL全文が入ります。 | [http://docs.repro.io/ja/dev/web/tracking.html?highlight=tracking#web-standard-event](http://docs.repro.io/ja/dev/web/tracking.html?highlight=tracking#web-standard-event) |
| path | ドメイン以降からクエリパラメータまでの文字列が入ります。 | /ja/dev/web/tracking.html |
| query | ?を含むクエリパラメータが入ります。 | ?highlight=tracking |
| referrer | 遷移元URLが入ります。 | [https://app.repro.io/](https://app.repro.io/) |
| title | ページのタイトルが入ります。 | イベントトラッキング — Repro ドキュメント |

##### NOTE
- canonical urlについての詳細は [こちら](https://en.wikipedia.org/wiki/Canonical_link_element) を参照してください
- og urlについての詳細は [こちら](http://ogp.me/) を参照してください



### 標準イベント

Reproではユーザーの行動分析を行う上で典型的なイベントを **標準イベント** として定義しています。 **標準イベント** をトラックする際はユーザーの行動に応じたAPIを呼び出してください。また、Webサイト独自のイベントをトラックする際は [カスタムイベント](#web-custom-event) をご利用ください。

以下の表は標準イベントのプロパティの一覧です。イベントによって指定できるプロパティが異なります。詳細は各APIの説明を参照してください。

| プロパティ名 | 説明 | 型 |
| --- | --- | --- |
| content_id | 商品やページを示すID | string |
| content_name | 商品やページの名前 | string |
| content_category | 商品やページのカテゴリ | string |
| value | 商品の金額 | double |
| currency | valueに指定した値の通貨単位 | string |
| num_items | 同一の商品の購入数 | integer |
| search_string | ユーザーが入力した検索文字列 | string |
| status | 登録状態 | string |
| service_name | サービスの名前 | string |

##### NOTE
- 必須でないプロパティは省略可能です。
- 独自のプロパティを追加したい場合は [独自プロパティの追加](#web-extra-properties) をご確認ください。

#### 閲覧

コンテンツの閲覧操作をトラックします。

**使用例**

- ユーザーが商品詳細画面を表示したとき

**プロパティ**

- content_id (**必須**、メソッドの第1引数に指定)
- content_name
- content_category
- value
- currency

```js-web
reproio("trackViewContent", "1234", {
  value: 5000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing"
});
```

#### 検索

検索する操作をトラックします。

**使用例**

- ユーザーが「検索」ボタンをタップしたとき

**プロパティ**

- content_id
- content_category
- value
- currency
- search_string

```js-web
reproio("trackSearch", {
  value: 3000.0,
  currency: "JPY",
  content_category: "Clothing & Shoes > Mens > Clothing",
  search_string: "Jeans",
  content_id: "1234"
});
```

#### カートに追加

カートに追加する操作をトラックします。

**使用例**

- ユーザーが「カートに入れる」ボタンをタップしたとき

**プロパティ**

- content_id (**必須**、メソッドの第1引数に指定)
- content_name
- content_category
- value
- currency

```js-web
reproio("trackAddToCart", "1234", {
  value: 5000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing"
});
```

#### ウィッシュリストに追加

ウィッシュリストに商品を追加する操作をトラックします。

**使用例**

- ユーザーが「ウィッシュリストに入れる」ボタンをタップしたとき

**プロパティ**

- content_id
- content_name
- content_category
- value
- currency

```js-web
 reproio("trackAddToWishlist", {
  value: 5000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing",
  content_id: "1234"
});
```

#### 支払い開始

購入手続きの開始をトラックします。

**使用例**

- ユーザーが「購入手続きへ」ボタンをタップしたとき

**プロパティ**

- content_id
- content_name
- content_category
- value
- currency
- num_items

```js-web
reproio("trackInitiateCheckout", {
  value: 8000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing",
  content_id: "1234"
});
```

#### 支払い情報追加

支払い情報の入力操作をトラックします。

**使用例**

- ユーザーが「支払情報を保存」ボタンをタップしたとき

**プロパティ**

- content_id
- content_category
- value
- currency

```js-web
reproio("trackAddPaymentInfo", {
  value: 8000.0,
  currency: "JPY",
  content_category: "Clothing & Shoes > Mens > Clothing",
  content_id: "1234"
});
```



#### 購入

購入操作をトラックします。

**使用例**

- ユーザーが「購入確定」ボタンをタップしたとき

**プロパティ**

- content_id (**必須**、メソッドの第1引数に指定)
- value (**必須**、メソッドの第2引数に指定)
- currency (**必須**、メソッドの第3引数に指定)
- content_name
- content_category
- num_items

```js-web
reproio("trackPurchase", "1234", 8000.0, "JPY", {
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing",
  num_items: 2
});
```

#### シェア

ソーシャル・ネットワーク (Facebook, Twitterなど) へのシェアをトラックします。

**使用例**

- ユーザーが「商品をシェアする」ボタンをタップしたとき

**プロパティ**

- content_id
- content_name
- content_category
- service_name

```js-web
reproio("trackShare", {
  content_category: "Clothing & Shoes > Mens > Clothing",
  content_name: "Slim Jeans",
  content_id: "1234",
  service_name: "twitter"
});
```

#### リード

サイトの試用開始をトラックします。ユーザー登録を必須としていないサイトでご利用ください。

**使用例**

- ユーザーが「試しに使ってみる」などのボタンをタップしたとき

**プロパティ**

- content_name
- content_category
- value
- currency

```js-web
reproio("trackLead", {
  value: 8000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing"
});
```

<!-- completeRegistration: -->

#### ユーザー登録

ユーザー登録の完了をトラックします。

**使用例**

- ユーザーが「ユーザー登録」をタップしたとき

**プロパティ**

- content_name
- value
- currency
- status

```js-web
reproio("trackCompleteRegistration", {
  value: 8000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  status: "completed"
});
```



#### 独自プロパティの追加

標準イベントには独自のプロパティを追加することもできます。 `extras` プロパティにオブジェクトをセットしてください。

##### NOTE
オブジェクトプロパティのキーが標準イベントのプロパティ名と重複する場合、オブジェクトの値は無視されます。

```js-web
reproio("trackViewContent", "1234", {
  value: 5000.0,
  currency: "JPY",
  content_name: "Slim Jeans",
  content_category: "Clothing & Shoes > Mens > Clothing",
  extras: {
    color: "blue",
    waist: 90
  }
});
```



### カスタムイベント

標準イベントとして定義されているもの以外の、Webサイト独自のイベントをトラックします。

##### NOTE
- `___repro___` から始まるイベント名は使用できません。
- イベント名にnullや空文字列は不可、上限は191文字です。

```js-web
// Custom event
reproio("track", "Finished tutorial");


// Custom event with properties
reproio("track", "user review", { rating: 3 });
```

### 管理画面からイベントを設定する

特定のURLを指定してイベントをトラッキングしたい場合はイベントトリガーがご利用いただけます。なお、イベントトリガーではイベントプロパティは登録できないため、イベントプロパティを利用したい場合は　[カスタムイベント](#web-custom-event) の設定をしてください。
 
詳細な設定方法につきましては、 [Web設定](https://docs.repro.io/ja/dashboard/setting/web-tracking-rule.md) をご確認ください。

---

## セッション・ライフサイクル

### Web

#### セッションの長さ

セッションの長さはユーザーの操作に依存します。長さに上限や下限はありません。

#### セッション開始

Web SDKの導入スニペットが埋め込まれたページをユーザーが開いたタイミング、もしくはユーザープロフィールのセット、イベントの実行、Web メッセージの表示が行われたタイミングでセッションが開始されます。ただし、該当のアクションが実行された過去30分間でユーザープロフィールのセット、イベントの実行、Web メッセージの表示が行われていた場合は、ページを閉じたりブラウザを終了させたとしても、前回のセッションが継続しているものとして扱われます。

---

## オプトアウト機能

Web SDKによるデータ収集とWebメッセージの表示を無効にしたい場合は、オプトアウト機能を利用してください。オプトアウト状態になるとSDKの動作は以下の通りとなります。

- セッションを開始しません
- Reproのサーバにデータを送信しません
- Webメッセージを表示しません

##### NOTE
- オプトアウトの状態はユーザー毎ではなくブラウザ毎の設定です。同一ユーザーが複数ブラウザ所持している場合、全てのブラウザでオプトアウトするにはブラウザ毎にオプトアウトの設定が必要です。
- ユーザープロフィール、イベントはオプトイン後にセットしてください。オプトアウト状態でセットしても無視されます。

##### WARNING
- オプトアウト機能はWeb SDKバージョン2 から利用できます。

### オプトインの初期状態の指定

オプトインの初期状態はsetupのオプションに `opt_out_by_default` を指定することができます。
デフォルトは `false` となり、初期状態はオプトイン状態になります。
初期状態をオプトアウト状態にしたい場合は、`true` を設定してください。初期状態の指定方法は次のようになります。

オプションの設定方法

```js-web
reproio("setup", "YOUR_REPRO_SDK_TOKEN", { opt_out_by_default: true });
```

### オプトインの指定

オプトインを設定するには `optIn` APIを利用することで、オプトアウト状態からオプトイン状態に切り替えることができます。

```js-web
reproio('optIn');
```

##### NOTE
- オプトアウト状態からオプトイン状態に変更したタイミングでセッションを開始します。

##### WARNING
- optIn APIを呼んだ後に必ず、reproio("setup", "YOUR_REPRO_SDK_TOKEN"); を呼び出してください。
- ユーザーIDも設定する場合は、optIn APIを呼び出した後に `setUserID` を設定しその後 `setup` を呼び出してください。

### オプトアウトの指定

オプトアウトを設定するには `optOut` APIを利用することで、オプトイン状態からオプトアウト状態に切り替えることができます。

```js-web
reproio('optOut');
```

### オプトイン/オプトアウトの状態を確認する

`isOptedIn` APIを利用することで、オプトイン/オプトアウトの状態を確認することができます。返り値はboolean型となります。
オプトイン状態の場合は `true` 、オプトアウト状態の場合は `false` の値が返ってきます。

```js-web
reproio('isOptedIn');
```

---

## バージョン1 から バージョン2 への更新手順

機能追加に伴う導入スニペットの更新頻度を下げるため、トラッキング用のインターフェイスを改良したバージョン2をリリースしました。
バージョン1からバージョン2へは次の手順で更新してください。

バージョン1はバージョン2のリリース後から数ヶ月後にサポート対象外になり、ご利用いただけなくなります。
サポート対象外となりますとReproの機能がご利用いただけなくなりますので、
お早めにバージョン2へアップデートしていただき、ご利用くださいますようお願いします。

### 導入スニペットの変更

スニペットを次のように変更してください。

変更前

```html
<script>
  !function(e,r,t){var o={c:null,d:null,e:[],f:[],g:[],h:[],i:[],setup:function(e,r){this.c=[e,r]},setUserID:function(e){this.d=e},track:function(e,r){this.e.push([e,r])},setStringUserProfile:function(e,r){this.f.push([e,r])},setIntUserProfile:function(e,r){this.g.push([e,r])},setDoubleUserProfile:function(e,r){this.h.push([e,r])},setDateUserProfile:function(e,r){this.i.push([e,r])}};window.reproio=window.reproio||o;var i=e.createElement(r),n=e.getElementsByTagName(r)[0];i.src="https://cdn.reproio.com/web/v1/repro-sdk.min.js",i.async=!0,i.onload=function(){if(o.d&&reproio.setUserID(o.d),o.c&&reproio.setup(o.c[0],o.c[1]),o.e.length>0)for(var e=0;e<o.e.length;e++)reproio.track(o.e[e][0],o.e[e][1]);if(o.f.length>0)for(e=0;e<o.f.length;e++)reproio.setStringUserProfile(o.f[e][0],o.f[e][1]);if(o.g.length>0)for(e=0;e<o.g.length;e++)reproio.setIntUserProfile(o.g[e][0],o.g[e][1]);if(o.h.length>0)for(e=0;e<o.h.length;e++)reproio.setDoubleUserProfile(o.h[e][0],o.h[e][1]);if(o.i.length>0)for(e=0;e<o.i.length;e++)reproio.setDateUserProfile(o.i[e][0],o.i[e][1])},n.parentNode.insertBefore(i,n)}(document,"script");
  reproio.setup("YOUR_REPRO_SDK_TOKEN")
</script>
```

変更後

```html
<script>
    !function(o,e,n){var r=[];if(window.reproio)console.info("Repro Web SDK was loaded more than once");else{window.reproio=function(){r.push(arguments)};var i=o.createElement(e),t=o.getElementsByTagName(e)[0];i.src="https://cdn.reproio.com/web/v2/repro-sdk.min.js",i.async=!0,i.crossOrigin="",i.onload=function(){window.reproio("setSnippetVersion","2.1"),r.forEach(function(o){window.reproio.apply(window.reproio,o)})},t.parentNode.insertBefore(i,t)}}(document,"script");
    reproio("setup", "YOUR_REPRO_SDK_TOKEN");
</script>
```

### ユーザーIDの変更

スニペットを次のように変更してください。

変更前

```js-web
reproio.setUserID("xxxxxxxxxxxx");
```

変更後

```js-web
reproio("setUserID", "xxxxxxxxxxxx");
```

### イベントの設定

スニペットを次のように変更してください。

変更前

```js-web
// Custom event
reproio.track("Finished tutorial");

// Custom event with properties
reproio.track("user review", { rating: 3 });
```

変更後

```js-web
// Custom event
reproio("track", "Finished tutorial");


// Custom event with properties
reproio("track", "user review", { rating: 3 });
```

### ユーザープロフィールの設定

スニペットを次のように変更してください。

String型の場合

変更前

```js-web
reproio.setStringUserProfile("Job", "Developer");
```

変更後

```js-web
reproio("setStringUserProfile", "Job", "Developer");
```

##### NOTE
- 他の型（例えば int型）の場合については [ユーザープロフィール](https://docs.repro.io/ja/dev/web/user-profile.md) をご参照ください。

---

## Webプッシュ通知

このページではWebプッシュ通知を送るまでの手順を説明します。

### ServiceWorkerファイルのダウンロードとホスティング

**管理画面 > Webプッシュ通知設定** から、 ServiceWorkerのファイルをダウンロードしてください。



上記でダウンロードしたファイルをお客様のwebサーバーにホスティングしてください。

- 例) **https://www.example.com** のURLでウェブサイトを公開している場合は、**https://www.example.com/web-push/sw.js** という形でファイルがアクセス出来るようにしてください。

### ServiceWorkerのホスト先の指定

先にホスティングしたServiceWorkerのファイルへの絶対URLを指定してください。



##### NOTE
- ServiceWorkerを設置したパスをscopeに指定してください。



##### WARNING
- ServiceWorkerのURLおよびスコープについては、一度設定した後には強い必要性がない限りは変えずにそのままにしてください。
- ServiceWorkerファイルを設置する場所については、サイトのルートディレクトリ（e.g. **https://example.com/sw.js**）ではなく別のディレクトリ配下（e.g. **https://example.com/web-push/sw.js**）に設置することを推奨します。
- 既にお客様がServiceWorkerをご利用されている場合に関して
  - Reproの提供するServiceWorkerとは別のServiceWorkerで "push" や "notificationclick" イベントリスナーが存在しないようにしてください。
  - すでにサイトで利用中のServiceWorkerが存在する場合、Reproの提供するServiceWorkerは既存のものと別のURLおよびスコープを設定するようにしてください。
  - すでに利用中のServiceWorkerとの干渉や調整が必要だと思われる場合は、あらかじめ弊社担当CSにご相談ください。

### manifestファイルの作成とホスティング（iOS用）

iOS端末に対してWebプッシュ通知を配信するためには、ServiceWorkerに加えてサイト上にmanifestファイルを設置する必要があります。manifestファイルの詳細については [https://developer.mozilla.org/ja/docs/Web/Manifest](https://developer.mozilla.org/ja/docs/Web/Manifest) を参照してください。

### 通知許諾を表示する

#### A）Web SDKのAPIを使う

お客様のwebサイト上の任意のタイミングで下記のようなAPIを呼び出すことで、Webプッシュ通知許諾ダイアログを出すことが可能です。すでにサイトで許諾している場合はダイアログは出ず、プッシュを購読したことになります。

```js-web
reproio('subscribeToPushNotification');
```

##### WARNING
- セットアップ計測タグの直後にこのAPIを呼び出すと、許諾ダイアログが出てこないことがあります。下記のような実装を検討してください。
  - セットアップ計測タグから数秒遅延させAPIを実行する
  - Webメッセージを利用する（下記参照）

#### B）Webメッセージ経由

カスタムメッセージを選択した上で、JavaScript内で下記のAPIを呼び出すことで、Webプッシュ通知許諾ダイアログを出すことが可能です。すでにサイトで許諾している場合はダイアログは出ず、プッシュを購読したことになります。

```js-web
reproio('subscribeToPushNotification');
```

##### WARNING
- ブラウザの制約により、Webプッシュ通知の **通知許諾ダイアログをユーザに出すタイミングは基本的に１回** のみです。
- 上記の制約があるため、Webプッシュ通知の通知許諾ダイアログを出せるタイミングに関しては、熟慮した上で決めることを推奨しております。
  - 通知許諾ダイアログを出すタイミングのベストプラクティスに関しては [https://repro.io/contents/why-people-are-turning-off-push/](https://repro.io/contents/why-people-are-turning-off-push/) をご参照ください。
- 当該のWebサイトでContent-Security-Policyを利用している場合は、`Content-Security-Policy` ヘッダに `worker-src: https://cdn.reproio.com` を追加してください。

### Webプッシュ通知が利用可能であることを確認する

下記 WebSDK API をページの JavaScript から、もしくはカスタムWebメッセージ内で呼び出すことにより、そのユーザーに対してWebプッシュ通知が配信可能であるかが確認できます。
この API の返り値を使ってページの要素の変更やメッセージの出し分けを行うことにより、Webプッシュ通知の対応環境でないユーザに通知の受け取りをオススメしてしまう、といったギャップを避けることができます。

```js-web
reproio('isPushNotificationSubscribeAllowed');
```

この API は現在のユーザが通知許可を未決定な場合も含み、潜在的に Webプッシュ通知を受け取り可能な状態であるかどうかを判定します。
具体的には以下の確認を行い、全ての条件に合致する場合に true を、それ以外の場合には false を返します。

1. Repro の Webプッシュ通知に対応していているブラウザを使用している
2. 既に通知を拒否済みでない (許可済みであるか、もしくは未決定状態である)
3. 管理画面の Webプッシュ通知機能が有効になっており、ServiceWorker URL が入力済みである
4. 管理画面で設定した ServiceWorker の URL オリジンと、アクセス中のものが合致している

---

## Repro Webの計測タグが正しく動いているか確認する

Repro Webの導入が正しくできているか確認するための方法を紹介します。

Repro Webが既に導入されていることが前提となります。
まだRepro Webを導入していない場合は、[開発ガイド] > [[導入](https://docs.repro.io/ja/dev/web/getstarted/web.md)] を参照してください。

また、確認のためのブラウザは [Google Chrome](https://www.google.com/intl/ja/chrome/) です。Google Chromeのデベロッパーツールの動作を例に解説します。

デベロッパーツールにアクセスするには、ページを右クリックし、[検証] をクリックします。



すると、デベロッパーツールが表示されます。



##### NOTE
デベロッパーツールの詳細な利用方法については、[Googleヘルプセンター](https://support.google.com/campaignmanager/answer/2828688?hl=ja) をご確認ください。

今回は下記4つの手順にて確認を行います。

1. [計測タグが正しく設置されているかを確認する](#measurement-tag-1)
2. [計測タグが正しく動作しているかを確認する](#measurement-tag-2)
3. [計測タグが正しく通信できているかを確認する](#measurement-tag-3)
4. [イベントトラッキングが正しく動作しているかを確認する](#measurement-tag-4)

それではそれぞれの確認方法を紹介します。



### 計測タグが正しく設置されているかを確認する

計測タグが正しく設置されているかは、ページに特定のScriptが埋められているかどうかで確認できます。

まずはタグを正しく埋められているページにアクセスをし、デベロッパーツールを開きます。

次に、Ctrl+F または command + F をクリックして検索フィールドを開きます。



検索フィールドに https://cdn.reproio.com と入力して検索をかけます。
以下のように https://cdn.reproio.com/ がハイライトされていれば計測タグが正しく設置されています。



##### NOTE
ハイライトされていない場合は計測タグが正しく設置されていません。
 
弊社のカスタマーサクセス担当、もしくはRepro管理画面の右下にあるアイコンよりチャットサポートへお問い合わせください。
 



### 計測タグが正しく動作しているかを確認する

次に計測タグが正しく動作できているか確認します。
デベロッパーツールを開き、タブ内の「Console」をクリックします。



コンソールモードになるので、 reproio('test') と入力しEnterキーをクリックしてください。



以下のように「false」と表示されていれば計測タグは正しく動作しています。



##### NOTE
赤色のエラー文の後に何も表示されていなければ動作に問題があります。
 
弊社のカスタマーサクセス担当、もしくはRepro管理画面の右下にあるアイコンよりチャットサポートへお問い合わせください。
 




### 計測タグが正しく通信できているかを確認する

次に計測タグが正しく通信できているか確認します。
デベロッパーツールを開き、タブ内の「Network」をクリックします。



検索フィールドにて「repro」と入力しEnterキーをクリックします。
configのStatusが 「200」 になっていれば正しく通信できています。



##### NOTE
**「repro」と検索してもヒットしない場合**

ページの読み込みを行う前にデベロッパーツールを開いていないと、「Network」で通信の状態を確認することができません。
デベロッパーツールの「Network」を開いた状態でページをリロードし、再度「repro」で検索をしてください。

##### NOTE
configのStatusが 「200」以外の場合、正しく通信されていません。
 
弊社のカスタマーサクセス担当、もしくはRepro管理画面の右下にあるアイコンよりチャットサポートへお問い合わせください。
 



### イベントトラッキングが正しく動作しているかを確認する

設定されているイベントが正しく動作しているかを確認します。
デベロッパーツールを開き、タブ内の「Network」をクリックします。



検索フィールドにて「repro」と入力しEnterキーをクリックします。



「event-chunks」をクリックします。



「Payload」タブをクリックします。



「events」をクリックすると、イベントの情報が確認できます。こちらに情報が入っていれば、トラッキングが動作している事になります。



以上ですべてのチェックは完了です。

##### NOTE
- 本記事の記載内容は、2022年8月26日執筆時点の情報です。今後Repro内部の仕様変更とブラウザの仕様変更により、記載の情報が古くなる可能性がございます。
- アップデートがあった際に記事の修正を行うよう努めておりますが、万が一情報に誤りがございましたら、管理画面のチャットよりご連絡頂けますと幸いです。

---

## Repro Webの利用するCookieについて

Repro Webは各種分析・マーケティング機能の提供を目的として次に示すCookieを使用して一定の情報を収集いたします。

| Key | 種別 | 説明 |
| --- | --- | --- |
| rpr_uid | ターゲティングCookie | Repro内でブラウザを識別するために発番したUUIDを記録する |
| rpr_cookie_available_check | 機能性Cookie | Repro Webの動作に必要なCookie利用可否の確認を目的に一時的に記録する（確認後削除されるため、一時的な動作検証用途） |
| rpr_is_first_session | 機能性Cookie | Repro Webが導入されて以降、初めてのページアクセスであったかの判定情報を保持する |
| rpr_opted_in | 機能性Cookie | Repro Webの動作可否を記録する |
| rpr_session_started_at | 機能性Cookie | Repro Webのセッション開始時刻を記録する |
| rpr_silver_egg_uid_key | 機能性Cookie | シルバーエッグ社との連携がある場合、シルバーエッグ社がユーザー識別を行うためのCookieキー名を記録する |
| rpr_event_last_tracked_at | 機能性Cookie | Repro Webが最後にイベントをトラックした時刻を記録する |

##### WARNING
- Cookieの名前や用途はRepro Webの内部仕様に準ずるものであり、予告なく変わることがあります。
- Cookieの種別に関しては弊社見解となります。どこまで厳格な分類を求めるかによって、機能性／ターゲティングの分類は異なる判断がされる可能性があります。

---

## オーディエンスインポート(β)

TreasureDataやSpin AppなどのDMPや、Domo、TableauなどのBIツールでセグメントしたユーザー群のリストを指定のS3パスに出力することで、プッシュ通知やアプリ内メッセージの配信対象にできます。

### はじめに

オーディエンスインポート機能はオプション機能です。ご利用希望の方は、管理画面右下のチャット、弊社の営業担当、もしくはカスタマーサクセスマネージャへお問い合わせください。

### ファイル仕様

UTF-8でテキストエンコーディングされた一行に単一のユーザーIDを指定した以下のようなCSVです。最大ファイルサイズは 500 MBで、これはユーザーIDが半角英数字の固定長30文字であれば約 1600 万件に相当します。

```
qwpeoifjadlskf
zxocjvasdfoiji
azxcpoqnadslpx
:
```

ファイルの拡張子は .csv でファイル名がオーディエンス名として利用されます。

##### NOTE
- Reproに登録されているユーザーのみが対象となります。Reproに登録されていないユーザーが含まれている場合は、それらのユーザーは対象からは除外されます。
- オーディエンスを利用したキャンペーンの配信対象ユーザーは、キャンペーンの配信時に取り込みが完了しているファイルが使われます。

### 取り込み頻度

オーディエンスの取り込みは10分間に1回の頻度で行われます。取り込まれたオーディエンスは管理画面上で [インポートオーディエンス](https://docs.repro.io/ja/dashboard/campaign/audience.md#user-list-upload) として扱われます。以前、取り込んだものと同名のファイルが更新された場合は、当該のオーディエンスが更新されます。

##### NOTE
- 各プロジェクトに設定されているオーディエンスの上限を超えてオーディエンスは作成されません。
- 何らかの理由でオーディエンスの作成・更新に失敗した場合、プロジェクトの管理者にあててメール通知が行われます。
- オーディエンスインポート(β)で作成したオーディエンスを削除する場合、管理画面でインポートオーディエンスを削除し、S3へアップロードしたファイルも削除してください。
- 管理画面でインポートオーディエンスを削除した場合、同名のファイルではオーディエンスを作成できません。
- 管理画面でインポートオーディエンスを削除せず、S3からファイルのみ削除された場合、キャンペーンは最後に取得したユーザーIDに配信されます。

---

## プッシュAPI

プッシュAPIを使うと、プッシュ通知をReproの管理画面からではなく、自社サービスのサーバーや、アプリなどお好きなところから配信できます。

### はじめに

プッシュAPIを使うには、APIエンドポイントとプッシュ通知用の Repro API トークンを生成する必要があります。



#### API エンドポイントとRepro API トークンの取得

1. **マーケティング > プッシュ通知** に行き、 **新しいプッシュ通知を作成する** をクリックしてください。
2. デフォルトの本文を設定します。
3. **APIを利用して配信** を選択してください。必要な場合は負荷分散機能をご利用ください。


1. プッシュ通知を公開してください。
2. 次のページでAPIエンドポイントと Repro API トークンが発行されます。



### API経由でプッシュ通知を配信する

プッシュAPIはHTTPの `POST` メソッドをうけつける単一のエンドポイントとひもづいています。

`POST https://marketing.reproio.com/v1/push/<push_id>/deliver`

#### 認証

取得した Repro API トークンをHTTPヘッダーの `X-Repro-Token` フィールドに設定してください。

#### 単位時間あたりのアクセス上限

プッシュAPIには、単位時間当たりのアクセス制限があります。

- アクセス上限設定値は、APIトークンごとに1分あたり1000件です。
- リクエストが正常に完了すると、レスポンスの `X-RateLimit-Limit` ヘッダーに単位時間あたりのリクエスト上限回数が記載されます。
- リクエスト数がアクセス上限数を超えると、 `HTTP Status 429 (Too Many Requests)` が返ります。

レスポンスヘッダーの詳細は [プッシュAPIのレスポンス](#push-api-response) をご覧ください。

##### WARNING
- アクセス上限設定値は予告なく変動する場合があります。
- アクセス上限設定値は、機能単位でのAPIトークンごととなります。
   
  例えば、プッシュAPIとユーザープロフィールAPIは同じAPIトークンを利用していますが、別機能のため同時にリクエストしたとしても、それぞれ１件づつのカウントとなります。
   



### APIフォーマット

メッセージをHTTP bodyにJSONフォーマットでセットします。
メッセージは 10MB 以内となります。それ以上の場合は user_ids を分割して複数回リクエストを行なってください。ユーザーIDを15バイトとした場合、設定できるユーザー数の上限はおよそ69万件ほどになります。

```json
{
  "audience": {
    "user_ids": [
      "user-1234"
    ]
  },
  "notification": {
    "message": "Hello!",
    "sound": "default.wav"
  }
}
```

#### 配信対象

- `audience`: 配信対象を指定します。
  - `user_ids`: アプリ内で [ユーザーID](https://docs.repro.io/ja/dev/sdk/user-id.md) APIを使って登録されたユーザーを配列で指定します。

#### メッセージ

- `notification`:

  下記の **スタンダード** 、 **カスタム (JSON)** のいずれかを含めます。
  フィールドが指定されていない場合、管理画面で作成したデフォルトのメッセージが配信されます。

##### スタンダード形式

- `message`:

  通知メッセージの本文です。
- `deeplink_url`:

  ディープリンクもしくはURLを設定すると、エンドユーザーが通知をタップしたときにそのアドレスをSDKが自動的に開きます。ディープリンクを指定した場合、アプリ内の特定のページを開きます（アプリ側の実装が必要です）。URLを指定した場合、ブラウザでWebページを開きます。未指定の場合は、アプリを通常起動します。
  - 文字列長
    - 最大: 1000文字
- `sound`:

  iOSアプリのサウンドファイルを指定します。ファイル名が指定されていない場合は、iOSのシステムサウンドが使われます。

##### カスタム (JSON)

下記のパラメータを使用する場合は、両方同時に指定してください。

片方の OS にのみカスタムペイロードを送信する場合は、不要な方のパラメータを `{}` (空のJSON) で指定してください。

- `custom_payload_ios`:

  iOS 向けの JSON 文字列を **String** で指定する必要があります。
- `custom_payload_android`:

  Android 向けの JSON 文字列を **String** で指定する必要があります。

バッジやサイレントプッシュ通知、カスタムペイロードなど、デフォルトのメッセージでは対応していない内容のメッセージを配信する場合はカスタム (JSON) 形式を選択してください。

##### NOTE
- **Android**: カスタム (JSON) 形式のメッセージをアプリケーションで受信するには [FirebaseMessagingServiceのonMessageReceivedを実装](https://docs.repro.io/ja/dev/sdk/push-notification/android.md#customize-receiver) する必要があります。
- **Android**: Android向けの JSON で "data" の中に含める key-value については、文字列のみ指定することができます。詳細については [FCMのドキュメント](https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages) をご確認ください。

詳しくはこちらの内容も参照ください。

- [プッシュAPI パラメータ廃止と追加 | カスタム（JSON）形式のプッシュ通知リクエスト方法が変わります](https://support.repro.io/hc/ja/articles/28275694476441)



#### 配信の予約

- `schedule`: 配信時刻を指定します。 (optional)

  パラメータに時刻を指定することで、配信の予約を行うことができます。指定しない場合は即時に配信されます。
  ISO8601 フォーマットに準拠した文字列のみセットできます。

  スケジュールに指定できるのは1ヶ月先までです。

  スケジュールの登録上限数は1時間あたり1000件です。この制限はAPIエンドポイントごとではなく、ひとつのアプリに設定されているすべてのAPIエンドポイント共通で適用されます。

```json
{
  "audience": {
    "user_ids": [
      "user-1234"
    ]
  },
  "notification": {
    "message": "Hello!",
    "sound": "default.wav"
  },
  "schedule": "2018-06-20T13:00:00+09:00"
}
```

#### 例

##### 1人のユーザーにメッセージを配信する

```json
{
  "audience": {
    "user_ids": [
      "user-1234"
    ]
  },
  "notification": {
    "message": "Hello!",
    "sound": "default.wav"
  }
}
```

##### 複数のユーザーにメッセージを配信する

```json
{
  "audience": {
    "user_ids": [
      "user-1234",
      "user-5678"
    ]
  },
  "notification": {
    "message": "Hello!",
    "sound": "default.wav"
  }
}
```

##### カスタムペイロードを使う

```json
{
  "audience": {
    "user_ids": [
      "user-1234"
    ]
  },
  "notification": {
    "custom_payload_ios": "{\"aps\":{\"alert\":{\"title\":\"hello\",\"body\":\"world\"},\"badge\":1}}",
    "custom_payload_android": "{\"data\":{\"rpr_title\":\"hello\",\"rpr_body\":\"world\"}}"
  }
}
```

###### リッチ通知を送る

プッシュAPIを利用してリッチ通知を送る場合、カスタムペイロードにリッチ通知に必要な情報を以下のように記載してください。

```json
{
  "audience": {
    "user_ids": [
      "user-1234"
    ]
  },
  "notification": {
    "custom_payload_ios": "{\"aps\": {\"alert\": {\"title\": \"YOUR_NOTIFICATION_TITLE\", \"body\": \"YOUR_NOTIFICATION_BODY\"}, \"mutable-content\": 1}, \"rpr_attachment\": {\"url\": \"IMAGE_URL\", \"type\": \"jpg\"}}",
    "custom_payload_android": "{\"data\":{\"rpr_title\":\"YOUR_NOTIFICATION_TITLE\",\"rpr_body\":\"YOUR_NOTIFICATION_BODY\", \"rpr_picture\":\"{\\\"type\\\": \\\"jpg\\\",\\\"url\\\": \\\"IMAGE_URL\\\"}\"}}"
  }
}
```

##### NOTE
リッチ通知を表示させるには、あらかじめ [リッチ通知の受信準備の実装](https://docs.repro.io/ja/dev/sdk/push-notification/ios.md#ios-receiving-rich-notification) がアプリ側で行われている必要があります。

#### cURLを使ってプッシュ通知を配信する

```sh
curl https://marketing.reproio.com/v1/push/xxxx/deliver \
--verbose \
--request POST \
--header "X-Repro-Token: MARKETING-TOKEN" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data-binary '{"audience": { "user_ids": ["user-1234", "user-5678"]}}'
```

##### WARNING
エンドポイントのドメインが repro.io から reproio.com に変更されます。
旧ドメインも引き続きご利用頂けますが、なるべく新しいドメインをご利用ください。

### 管理画面から通知を配信する

プッシュAPIを管理画面から使うこともできます。これは、開発者の助けを借りずにマーケター自身でキャンペーンを打つための機能です。



この機能には下記の制限があります。ご注意ください。

- 配信されるメッセージは通知の作成画面で設定したものです。
- 配信対象ユーザーは下記に示すフォーマットの、ユーザーIDのリストで指定する必要があります。
  - 文字コード: UTF8
  - 改行コード: LF または CRLF
  - ファイルサイズ: 10MBまで
  - ファイルフォーマット:

```text
user-1234
user-5678
```



### プッシュAPIのリクエスト

**リクエストヘッダー**

リクエストのヘッダーには、以下の値を設定します。

| ヘッダー | 説明 | 必須 |
| --- | --- | --- |
| Content-Type | application/jsonを指定します。 | 必須 |
| X-Repro-Token | [API エンドポイントとRepro API トークンの取得](#push-api-get-api-token) で取得したトークンを指定します。 | 必須 |

**リクエストボディ**

メッセージをJSONフォーマットで設定します。



### プッシュAPIのレスポンス

**レスポンスヘッダー**

レスポンスのヘッダーには、以下の値が含まれます。

| ステータス | ヘッダー | 説明 |
| --- | --- | --- |
| 正常 | `X-RateLimit-Limit` | 単位時間あたりのアクセス上限 |
| 正常 | `X-RateLimit-Remaining` | アクセスできる残り回数 |
| 正常 | `X-RateLimit-Reset` | アクセス数がリセットされる時刻(unixtime) |
| リクエスト制限 | `Retry-After` | 再実行可能になるまでの秒数 |

**レスポンスボディ**

プッシュAPIをコールした際の、レスポンスに含まれるステータスコードとエラーメッセージの一覧は下記になります。

#### 202 Accepted

リクエストが成功しました。

レスポンスボディ:

```json
{
  "status": "accepted"
}
```

#### 400 Bad Request

リクエストにエラーがあります。タイプミスなどがないかご確認ください。

レスポンスボディ:

```json
{
  "error":"message"
}
```

#### 401 Unauthorized

Repro API トークンが指定されていません。

レスポンスボディ:

```json
{
  "status": "unauthorized",
  "error": {
    "messages": [
      "Please include your Repro API Token as \"X-Repro-Token\" HTTP header."
    ]
  }
}
```

#### 403 Forbidden

指定した Repro API トークンが間違っています。

レスポンスボディ:

```json
{
  "status": "forbidden",
  "error": {
    "messages": [
      "Please check your Repro API Token as \"X-Repro-Token\" HTTP header."
    ]
  }
}
```

#### 404 Not Found

エンドポイントが存在しません。

レスポンスボディ:

```json
{
  "status": "not_found",
  "error": {
    "messages": [
      "Not found."
    ]
  }
}
```

#### 422 Unprocessable Entity

指定したパラメータが間違っています。

レスポンスボディ:

```json
{
  "status": "unprocessable_entity",
  "error": {
    "messages": [
      "audience is missing",
      "audience[user_ids] is missing"
    ]
  }
}
```

#### 413 Payload Too Large

リクエストの内容が大きすぎます。

レスポンスボディ:

```json
{
  "status": "payload_too_large",
  "error": {
    "messages": [
      "client intended to send too large body"
    ]
  }
}
```

#### 429 Too Many Requests

リクエスト数が多すぎます。 `Retry-After` ヘッダーに記載された秒数待った後、リクエストを再開してください。

レスポンスボディ:

```json
{
  "status": "too_many_requests",
  "error": {
      "messages": [
          "Too many requests hit the API too quickly."
      ]
  }
}
```

---

## イベントバルクトラッキング (β)

本機能は、複数ユーザーがそれぞれ実行した行動やステータスの変化を **イベント** として扱い、CSVによって一括で Repro にインポートするための機能です。

### 参考

イベントの基本的な使い方は以下をご参照ください。

* [イベントをトラックする](https://docs.repro.io/ja/dev/sdk/getstarted/next.md)

本機能ではなく、SDKからイベントをトラックする場合には以下のドキュメントをご参照ください。

* [イベントトラッキング(SDK)](https://docs.repro.io/ja/dev/sdk/tracking.md)
* [イベントトラッキング(Web)](https://docs.repro.io/ja/dev/web/tracking.md)

### はじめに

イベントバルクトラッキングはオプション機能です。ご利用希望の方は、管理画面右下のチャットもしくは弊社の営業担当へお問い合わせください。

#### CSVファイルについて

イベントバルクトラッキングは、CSVファイルを利用してイベント取り込みを行います。

##### ファイルフォーマット

```
user_id,event_name,event_properties
123456,event_1,"{""key1"":""value1"",""key2"":""value2""}"
234567,event_2,"{""key1"":""value1"",""key2"":""value2""}"
```

##### ファイル形式

* 文字コード: UTF-8
* 改行コード: LF
* ヘッダー: `user_id,event_name,event_properties`

##### フィールドの詳細

| 名前 | 型 | 最大桁数 | 必須 | 説明 |
| --- | --- | --- | --- | --- |
| user_id | string | 191文字 | ✅ | Reproにイベントを登録したい [ユーザーID](https://docs.repro.io/ja/dev/sdk/user-id.md) を指定します。存在しないユーザーIDを指定した場合、ユーザーの作成が行われます。 |
| event_name | string | 191文字 | ✅ | イベント名 (詳細は後述) |
| event_properties | string | 10kB <sup>[1](#key-value-limitation)</sup> |  | イベントプロパティの JSON をエスケープした文字列。RFC 4180にしたがって `event_properties` 全体をダブルクォーテーションで囲み、内部のダブルクォーテーションは連続した2つのダブルクォーテーションでエスケープします。例: ```text "{""key1"":""value1"",""key2"":""val2""}" ``` |
* <a id='key-value-limitation'>**[1]**</a> イベントプロパティの key 名は 48 文字まで、値は 191 文字までとなります。1イベントのイベントプロパティ全体で 10KB まで許容します。

###### 過去に一度でもRepro上でイベントトラッキングされたイベントデータ

* イベント一覧に表示されており、なおかつトグルボタンが **On** のイベントのみ登録が可能です。インポートできない場合、対象イベントのトグルが Off になっていないか確認してください。

###### event_nameに設定する値

* Reproにすでにトラッキングされているイベントの場合、 `event_name` の値は `イベント > イベント設定` 画面のイベント一覧に表示されるイベント名（赤枠部分）を指定します。



###### イベントの新規作成

* `___repro___` で始まるイベント名は登録できず、トラッキングもされません。
* イベント一覧に存在しない `event_name` を指定した場合は新規作成され、表示名にはその `event_name` が利用されます (後から `イベント > イベント設定` で変更可能)。
* 作成可能なイベントの制約はカスタムイベント仕様に準拠します。
  * 仕様を満たさない値の場合は登録処理に失敗します。詳しくは [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md) の「カスタムイベント仕様」を参照してください。
  * 登録可能イベント数を超えた場合はイベント名は登録されますが Off 状態となり、ユーザーがトラッキングしたイベントとしては登録されません。

###### イベントプロパティ

* イベントプロパティに利用できるJSONのフォーマットは以下の通りです。
  : * key: String のみ (最大 48 文字)
    * value: String のみ (最大 191 文字)
    * 1イベントのイベントプロパティ全体で10KBまで
* 参考: [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md)

### 利用方法

#### 管理画面 (app.repro.io) からアップロードする場合

1. ダッシュボード左ナビゲーションバーから「イベント」をクリックし「データインポート (β)」を開きます。

> 
1. 「CSVファイルをアップロード」をクリックし、インポート対象イベントが記載された CSV を選択してアップロードします。

> 
1. CSV アップロード成功後、処理開始の通知が表示され非同期処理が開始されます。

> 
1. 処理完了すると登録完了メールが送信されます。

> 

#### S3へ CSV ファイルをアップロードする場合

Repro が提供する Amazon S3 バケットへ直接 CSV をアップロードしてインポートを実行できます。利用には S3 のアクセスキー発行が必要です。

アクセスキー発行手順

1. ダッシュボードで **設定 > プロジェクト設定** を開きます。
2. 「認証情報」タブに切り替え、「AMAZON S3 アクセスキーを追加」をクリックします。

> 
1. ポップアップに表示された「アクセスキーID」「シークレットアクセスキー」を安全な場所に保管してください (シークレットは一度閉じると再表示不可)。

> 

##### IMPORTANT
プロジェクト設定画面に「Amazon S3 アクセスキー」セクションが表示されない場合は担当 CS へお問い合わせください。

##### NOTE
アクセスキー発行後、「データインポート (β)」画面にもアクセスキーIDが表示されます。



##### S3 バケットとパス

* バケット名: `repro-data-store`
* パス形式: `/$YOUR_APP_ID/event_bulk_tracking/YOUR_EVENT_FILE.csv`

`$YOUR_APP_ID` には「データインポート (β)」画面に表示される App ID を指定してください。

> 

`YOUR_EVENT_FILE.csv` にはアップロードするファイル名を指定します。

##### AWS CLI でのアップロード例

S3 URI: `s3://repro-data-store/$YOUR_APP_ID/event_bulk_tracking/YOUR_EVENTS_FILE.csv`

```console
$ aws s3 cp YOUR_EVENTS_FILE.csv s3://repro-data-store/$YOUR_APP_ID/event_bulk_tracking/YOUR_EVENTS_FILE.csv
```

#### S3 アップロード時の制限 / 推奨事項

##### 制限

* ファイル名は空白を含められません。
* ファイル名に `/` を含められません。
* ファイルの文字エンコードは UTF-8 である必要があります。

##### 推奨

以下に該当する場合は取り込みは行われますが動作保証対象外です。

* 既に取り込み済みのファイルと同一ファイル名
* ファイル名に英数字以外が含まれる
* 直前のアップロードから 5 分以内の再アップロード

### 処理内容

アップロードされた CSV の情報を元に複数のイベントデータを一括で Repro にインポートします。処理は非同期で、完了後にメールで結果が通知されます。メールは「設定 > メール通知」がオンのメンバー全員に送信されます。

エラーが発生した場合、メールに記載されたリンクからエラー行が含まれる CSV (理由付き) をダウンロードできます。

* エラーCSVファイル

  インポート失敗メールのリンクからダウンロードしたCSVファイルのフォーマットは下記の通りです

| user_id | event_name | event_properties |  |
| --- | --- | --- | --- |
| user_id | イベント名 | イベントプロパティ | 失敗理由 |
* エラー CSV 例
  ```
  user_id,event_name,event_properties
  ,ebt-sample,,"'user_id' が不正な値です"
  ```

### 制限事項

* イベントデータのインポート処理は非同期実行です。
  : * アップロード完了後にイベントデータのインポート処理が開始するまでの時間は保証しません。
    * 処理完了までの最長時間については保証しません。
    * 上記の通り呼び出しから発火までの時間が保証されていない為、イベント起点プッシュのキャンセルイベントに利用する場合はイベント起点プッシュ側で十分な待ち時間を用意する必要があります。動作保証するものではありませんが、最低でも30分以上待たないと想定外の方にプッシュを配信してしまうことが起こりえます。
* イベントバルクトラッキングは、一度に複数のイベントを発火させる前提です。一度に1つのイベントだけを発火させる使い方は想定しておりません。このような使い方をされる場合は担当CSまでご相談ください。
* CSVファイルには以下制限があります。
  : * イベントデータ件数の上限
      : * イベントデータ件数の上限は1ファイルあたり100万件です。
        * 上限を超過した場合、取り込み処理に失敗します。
        * 上限件数は今後変動する可能性があります。
    * ファイルサイズの上限
      : * app.repro.ioからファイルをアップロードする場合、ファイルサイズの上限は1ファイルあたり150MBです。
          : * 上限を超過した場合、ファイルをアップロードできず、インポート処理が開始されません。
        * S3バケットへの直接CSVファイルをアップロードする場合、ファイルサイズの上限は1ファイルあたり500MBです。
          : * 上限サイズは今後変動する可能性があります。
* アクセス分析など各種アナリティクス機能は、イベントバルクトラッキング経由のデータを集計しません。当該イベントを利用した場合、集計結果は0となります。

### その他

* ベータ提供です。利用には [Repro ベータテストサービス利用規約](https://repro.io/company/legal/term/betatest-service/) への同意が必要です。

##### NOTE
仕様・上限値は予告なく変更される可能性があります。

---

## イベントをトラックする

意味のある分析や、マーケティング施策を実施するためには、適切なユーザーグループを絞り込むことが重要です。イベントをトラックしてユーザーの行動を記録することにより、管理画面上で目的に応じた適切なユーザーグループを選択することができるようになります。

イベントを用いたユーザーグループ指定の例:

- [キャンペーンの作成画面で、イベントやユーザープロフィールを組み合わせて、配信対象となるユーザーグループを指定する](https://docs.repro.io/ja/dashboard/campaign/target.md)

どういうイベントをとるべきかわからない場合は、まず各画面の表示時にイベントをとってみることをおすすめします。

例:

```objc
@implementation MainViewController

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [Repro track:@"MainViewController" properties:nil];

    ...
}
```

```swift
class MainViewController: UIViewController {

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        Repro.track(event: "MainViewController", properties: [:])

        ...
    }
```

```java
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onResume() {
        super.onResume();
        Repro.track("MainActivity");

        ...
    }
}
```

```kotlin
class MainActivity : AppCompatActivity() {

    override fun onResume() {
        super.onResume()
        Repro.track("MainActivity")

        ...
    }
}
```

```cpp
#include "ReproCpp.h"

...

ReproCpp::track("Initialized");
```

```csharp
Repro.Track ("Initialized");
```

```js-cordova
// Will be written later
```

```js-react-native
class MainScreen extends React.Component {

    componentDidMount() {
        Repro.track("MainScreen", {});
    }

    ...
 }
```

```js-expo
import Repro from 'react-native-repro';

...

Repro.track("MainScreen", {});
```

```dart
import 'package:repro_flutter/repro.dart';

...

await Repro.track("Initialized");
```

## ユーザーIDをセットする

Repro では分析結果はユーザー単位で集計しています。ユーザーIDをセットすることにより、下記のメリットがあります:

- 複数のデバイスを使っているユーザーを同一視できる
- キャンペーンの配信対象の抽出がより精緻になる

詳しくは [こちら](https://docs.repro.io/ja/dev/sdk/user-id.md) をご覧ください。

## プッシュ通知を配信する

Reproでは、管理画面もしくはAPIからプッシュ通知配信をすることができます。プッシュ通知配信をするための実装は [こちら](https://docs.repro.io/ja/dev/sdk/push-notification/index.md) をご覧ください。

## Next...

その他の機能についての詳細は、以下をご覧ください。

- [セッション・ライフサイクル](https://docs.repro.io/ja/dev/sdk/session.md)
- [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md)
- [ユーザーID](https://docs.repro.io/ja/dev/sdk/user-id.md)
- [デバイスID](https://docs.repro.io/ja/dev/sdk/device-id.md)
- [ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md)
- [WebView](https://docs.repro.io/ja/dev/sdk/webview.md)
- [オプトアウト機能](https://docs.repro.io/ja/dev/sdk/optout/index.md)
- [アプリ内メッセージ](https://docs.repro.io/ja/dev/sdk/in-app-message.md)
- [プッシュ通知](https://docs.repro.io/ja/dev/sdk/push-notification/index.md)
- [Adjustで取得したアトリビューションデータをReproにセットする](https://docs.repro.io/ja/dev/sdk/integrate-adjust.md)
- [AppsFlyerで取得したアトリビューションデータをReproにセットする](https://docs.repro.io/ja/dev/sdk/integrate-appsflyer.md)

---

## ニュースフィードAPI

ニュースフィードAPIを使うと、[ニュースフィード](https://docs.repro.io/ja/dev/sdk/newsfeed.md) をAPI経由で取得出来ます。

例えば、お知らせ画面を実装するためにニュースフィードの機能を利用することを例に取ります。
この場合、Repro SDK経由してニュースフィードを取得する方法では、アプリ側でお知らせ画面を全て実装して頂く必要がございますが、APIを利用する方法では例えば [HTMLアプリ内メッセージ](https://docs.repro.io/ja/dashboard/campaign/html-in-app-message.md) の機能と組み合わせることで、お知らせ画面のUI及びニュースフィードの取得処理をRepro上で実装し、ニュースフィード機能の導入を楽にするといったことが可能になります。

##### NOTE
ニュースフィードAPIと [HTMLアプリ内メッセージ](https://docs.repro.io/ja/dashboard/campaign/html-in-app-message.md) を組み合わせて用いた場合でも、ニュースフィード機能を導入する上で必要な実装が完全になくなるわけではございませんので、ご注意ください。

##### WARNING
アプリ内メッセージおよびWebメッセージをニュースフィードとして利用する際には、仕様上下記のようなユースケースでは意図した挙動とならないことがございますのでご注意ください。

例) 購入イベントをトリガーにして、作成されたキャンペーンをニュースフィードとして利用する場合

- ニュースフィードはキャンペーンとは別に独立して作成されるため、キャンペーンが表示されていなくてもニュースフィードとしては取得が可能になります。

### はじめに

ニュースフィードAPIを使うには、Repro Client トークンを利用する必要があります。



#### Repro Client トークンの取得

1. **設定 > プロジェクト設定** に行き、 **認証情報 > Repro Client トークン** を確認します。



#### 単位時間あたりのアクセス上限

ニュースフィードAPIには単位時間当たりのアクセス上限があります。

- アクセス上限設定値は、1プロジェクトごとに1分あたり3000件です。
- リクエストが正常に完了すると、レスポンスの X-RateLimit-Limit ヘッダーに単位時間あたりのリクエスト上限回数が記載されます。
- リクエスト数がアクセス上限数を超えると、 HTTP Status 429 (Too Many Requests) が返ります。

レスポンスヘッダーの詳細 [レスポンスヘッダー](https://docs.repro.io/ja/dev/audience-api/index.md#response-header) をご覧ください。

##### WARNING
- アクセス上限設定値は予告なく変動する場合があります。
- アクセス上限設定値は、機能単位でのAPIトークンごととなります。
   
  例えば、プッシュAPIとユーザープロフィールAPIは同じAPIトークンを利用していますが、別機能のため同時にリクエストしたとしても、それぞれ１件づつのカウントとなります。
   

### ニュースフィードAPI

現在、ニュースフィードAPIでは下記の機能を提供しています。

| 機能 | HTTPメソッド | エンドポイント |
| --- | --- | --- |
| 取得 | `GET` | `https://api.reproio.com/v3/newsfeeds?device_id={device_id}&campaign_type={campaign_type}&limit={limit}&offset_newsfeed_id={offset_newsfeed_id}` |
| 更新 | `PATCH` | `https://api.reproio.com/v3/newsfeeds/{newsfeed_id}?device_id={device_id}&shown={shown}&read={read}` |

以降では、リクエスト方法の詳細を記載していきます。

#### ニュースフィードの取得

`GETリクエスト` を実行することで、最新のニュースフィードの取得が可能です。

#### エンドポイント

| 機能 | HTTPメソッド | エンドポイント |
| --- | --- | --- |
| 取得 | `GET` | `https://api.reproio.com/v3/newsfeeds?device_id={device_id}&campaign_type={campaign_type}&limit={limit}&offset_newsfeed_id={offset_newsfeed_id}` |

#### リクエストヘッダー

| ヘッダー | 説明 | 任意 / 必須 |
| --- | --- | --- |
| Content-Type | application/jsonを指定します。 | 必須 |
| X-Repro-Token | [Repro Client トークンの取得](#repro-client-token-newsfeed) で取得したトークンを指定します。 | 必須 |

#### クエリパラメーター

| フィールド | 説明 | 任意 / 必須 |
| --- | --- | --- |
| device_id | 取得処理を実行する端末のデバイスID。デバイスIDの取得方法に関しては、[デバイスID](https://docs.repro.io/ja/dev/sdk/device-id.md) をご参照ください。 | 必須 |
| campaign_type | 取得したいキャンペーンの種類。指定可能な値は下記の通りです。何も指定しなかった場合は、プッシュ通知を取得します。 : - **all** : すべてのキャンペーン種別 - **push_notification** : プッシュ通知 - **web_message** : Webメッセージ - **in_app_message** : アプリ内メッセージ | 任意 |
| limit | 取得するニュースフィードの件数を指定します。何も指定しなかった場合は、**最新の20件** が取得されます。 : - limitに指定できる最大値は **200** です。それ以上の値が指定された場合にはエラーレスポンスが返ってくるのでご注意ください。 | 任意 |
| offset_newsfeed_id | オフセットID。詳細は [ニュースフィード](https://docs.repro.io/ja/dev/sdk/newsfeed.md) をご参照ください。 | 任意 |

##### NOTE
ニュースフィードとして取得可能な期間はAPIのリクエスト日を起点にして、30日以内に実行されたキャンペーンです。ご注意ください。

#### レスポンスヘッダー

レスポンスのヘッダーには、以下の値が含まれます。

| ステータス | ヘッダー | 説明 |
| --- | --- | --- |
| 正常 | `X-RateLimit-Limit` | 単位時間あたりのアクセス上限 |
| 正常 | `X-RateLimit-Remaining` | アクセスできる残り回数 |
| 正常 | `X-RateLimit-Reset` | アクセス数がリセットされる時刻(unixtime) |
| 正常 | `Link` | 後続のニュースフィードを取得するためのパラメータ |
| リクエスト制限 | `Retry-After` | 再実行可能になるまでの秒数 |

#### 正常系レスポンス

リクエスト成功時、レスポンスボディはJSON形式で以下の内容が返ってきます。

| フィールド | 説明 |
| --- | --- |
| newsfeed_id(string) | ニュースフィードのID |
| campaign_type(string) | キャンペーン種別。**push_notification**, **web_message** , **in_app_message** のいずれかの値を取る。 |
| device_id(string) | 端末にひもづくデバイスID。詳細は、[デバイスID](https://docs.repro.io/ja/dev/sdk/device-id.md) をご参照ください。 |
| title(string) | ニュースフィードのタイトル |
| summary(stinrg) | キャンペーン作成時にニュースフィードの概要で指定された値 |
| body(string) | ニュースフィードの本文 |
| shown(boolean) | 表示されたかどうかの管理に利用する値 |
| read(boolean) | 既読かどうかの管理に利用する値 |
| link_url(string) | リンクのURL |
| image_url(string) | 画像のURL |
| extras(object) | カスタムペイロード |
| delivered_at(string) | 送信日時 |

#### 正常系レスポンスボディ例

```json
[
    {
        "newsfeed_id": 1,
        "campaign_type": "push_notification",
        "device_id": "12e4dd50-810a-410a-b046-8ce88729f1a1",
        "title": "quae",
        "summary": "Quam rerum aut incidunt.",
        "body": "Quam rerum aut incidunt.",
        "shown": true,
        "read": true,
        "link_url": null,
        "image_url": null,
        "extras": null,
        "delivered_at": "2021-06-07T09:27:53Z"
    }
]
```

##### WARNING
値の存在しないレスポンスの値は **null** もしくは　**""** の両方があり得ます。ご注意ください。

#### エラーレスポンス

レスポンスに含まれるステータスコードとエラーメッセージの一覧は下記になります。

#### 400 Bad Request

リクエストにエラーがあります。エラーメッセージを確認の上、対応してください。

**device_id** が指定されていません。

レスポンスボディ:

```json
{
  "error": {
    "messages": [
      "device_id is missing"
    ]
  }
}
```

**limit** に不正な値が指定されています。

レスポンスボディ:

```json
{
  "error": {
    "messages": [
      "limit must be less than or equal 200"
    ]
  }
}
```

**campaign_type** に不正な値が指定されています。

レスポンスボディ:

```json
{
  "error": {
    "messages": [
      "unknown campaign_type. valid campaign_type:all,push_notification,in_app_message,web_message"
    ]
  }
}
```

#### 401 Unauthorized

Repro Client トークンが指定されていません。

レスポンスボディ:

```json
{
  "status": "unauthorized",
  "error": {
    "messages": [
      "Please include your Repro Client Token as \"X-Repro-Token\" HTTP header."
    ]
  }
}
```

#### 403 Forbidden

指定した Repro Client トークンが間違っています。

レスポンスボディ:

```json
{
  "status": "forbidden",
  "error": {
    "messages": [
      "Please check your Repro Client Token as \"X-Repro-Token\" HTTP header."
    ]
  }
}
```

#### 404 Not Found

取得項目が存在しません。

レスポンスボディ:

```json
{
  "status": "not_found",
  "error": {
    "messages": [
      "Entity was not found."
    ]
  }
}
```

#### 429 Too Many Requests

リクエスト数が多すぎます。 `Retry-After` ヘッダーに記載された秒数待った後、リクエストを再開してください。

レスポンスボディ:

```json
{
  "status": "too_many_requests",
  "error": {
    "messages": [
      "Too many requests hit the API too quickly."
    ]
  }
}
```

#### ニュースフィードの更新

`PATCHリクエスト` を実行することで、ニュースフィードの既読や表示等の状態の更新が可能です。

#### エンドポイント

| 機能 | HTTPメソッド | エンドポイント |
| --- | --- | --- |
| 更新 | `PATCH` | `https://api.reproio.com/v3/newsfeeds/{newsfeed_id}?device_id={device_id}&shown={shown}&read={read}` |

#### リクエストヘッダー

| ヘッダー | 説明 | 任意 / 必須 |
| --- | --- | --- |
| Content-Type | application/jsonを指定します。 | 必須 |
| X-Repro-Token | [Repro Client トークンの取得](#repro-client-token-newsfeed) で取得したトークンを指定します。 | 必須 |

#### クエリパラメータ

| フィールド | 説明 | 任意 / 必須 |
| --- | --- | --- |
| newsfeed_id(string) | 更新処理を行う対象のニュースフィードのid。 | 必須 |
| device_id(string) | 更新処理を実行する端末のデバイスID。デバイスIDの取得方法に関しては、[デバイスID](https://docs.repro.io/ja/dev/sdk/device-id.md) をご参照ください。 | 必須 |
| shown(boolean) | 表示管理を行う値 | 任意( **readを指定しない場合は必須** ) |
| read (boolean) | 既読管理を行う値 | 任意( **shownを指定しない場合は必須** ) |

#### レスポンスヘッダー

レスポンスのヘッダーには、以下の値が含まれます。

| ステータス | ヘッダー | 説明 |
| --- | --- | --- |
| 正常 | `X-RateLimit-Limit` | 単位時間あたりのアクセス上限 |
| 正常 | `X-RateLimit-Remaining` | アクセスできる残り回数 |
| 正常 | `X-RateLimit-Reset` | アクセス数がリセットされる時刻(unixtime) |
| リクエスト制限 | `Retry-After` | 再実行可能になるまでの秒数 |

#### 正常系レスポンス

リクエスト成功時、レスポンスボディはJSON形式で以下の内容が返ってきます

| フィールド | 説明 |
| --- | --- |
| updated(boolean) | 更新処理が成功したかどうかを表します。 |

#### 正常系レスポンスボディ例

```json
{
    "updated": true
}
```

#### エラーレスポンス

#### 400 Bad Request

リクエストにエラーがあります。エラーメッセージを確認の上、対応してください。

**device_id** が指定されていません。

レスポンスボディ:

```json
{
  "error": {
    "messages": [
      "device_id is missing"
    ]
  }
}
```

**shownとread** のいずれも指定されていません。

レスポンスボディ:

```json
{
    "error": {
        "message": [
            "Either shown or read must be present"
        ]
    }
}
```

#### 401 Unauthorized

Repro Client トークンが指定されていません。

レスポンスボディ:

```json
{
  "status": "unauthorized",
  "error": {
    "messages": [
      "Please include your Repro Client Token as \"X-Repro-Token\" HTTP header."
    ]
  }
}
```

#### 403 Forbidden

指定した Repro Client トークンが間違っています。

レスポンスボディ:

```json
{
  "status": "forbidden",
  "error": {
    "messages": [
      "Please check your Repro Client Token as \"X-Repro-Token\" HTTP header."
    ]
  }
}
```

#### 404 Not Found

更新対象項目が存在しません。

レスポンスボディ:

```json
{
  "status": "not_found",
  "error": {
    "messages": [
      "Target newsfeed is not found"
    ]
  }
}
```

#### 429 Too Many Requests

リクエスト数が多すぎます。 `Retry-After` ヘッダーに記載された秒数待った後、リクエストを再開してください。

レスポンスボディ:

```json
{
  "status": "too_many_requests",
  "error": {
    "messages": [
      "Too many requests hit the API too quickly."
    ]
  }
}
```

---

## 削除ユーザー登録API

削除ユーザー登録APIを使うと、Reproのデータベースからユーザー情報を削除することができます。

##### NOTE
- リクエスト受付日の約6日後から削除処理が始まり、キャンペーン対象から除外されます。削除処理を開始した翌月の7日に削除処理が完了します。リクエスト受付日によっては完了が翌々月の7日になることもあります。
- 削除ユーザー登録APIを実行してから、削除されるまでの間に同じユーザー情報が送られた場合、その情報も合わせて削除されます。

##### WARNING
削除ユーザー登録APIはキャンセルできません。ご注意の上ご利用ください。

### はじめに

削除ユーザー登録APIを使うには、Repro API トークンを利用する必要があります。



#### Repro API トークンの取得

1. **設定 > プロジェクト設定** に行き、 **認証情報 > Repro API トークン** を確認します。



##### WARNING
「APIトークンの再発行」をすると既存のAPIトークンを利用できなくなり、あとから復元することはできません。

### 削除したいユーザーを登録する

削除ユーザー登録APIはHTTPの `POST` メソッドを受けつけるエンドポイントと紐付いています。

`POST https://api.reproio.com/v3/user_data_deletions`

#### 認証

取得した Repro API トークンをHTTPヘッダーの `X-Repro-Token` フィールドに設定してください。

#### 単位時間あたりのアクセス上限

削除ユーザー登録APIには、単位時間当たりのアクセス制限があります。

- アクセス上限設定値は、APIトークンごとに1分あたり1000件です。
- リクエストが正常に完了すると、レスポンスの `X-RateLimit-Limit` ヘッダーに単位時間あたりのリクエスト上限回数が記載されます。
- リクエスト数がアクセス上限数を超えると、 `HTTP Status 429 (Too Many Requests)` が返ります。

レスポンスヘッダーの詳細は [削除ユーザー登録APIのレスポンス](#user-data-deletions-api-response) をご覧ください。

##### WARNING
- アクセス上限設定値は予告なく変動する場合があります。
- アクセス上限設定値は、機能単位でのAPIトークンごととなります。
   
  例えば、プッシュAPIとユーザープロフィールAPIは同じAPIトークンを利用していますが、別機能のため同時にリクエストしたとしても、それぞれ１件づつのカウントとなります。
   



#### APIフォーマット

メッセージをHTTP bodyにJSONフォーマットでセットします。

- `identity_type`: `user_id` 固定です。
- `identity_value`: アプリやWebサイト内で [ユーザーID](https://docs.repro.io/ja/dev/sdk/user-id.md) APIを使って登録されたユーザーのIDを指定します。
  - 登録されていないユーザーの場合は、 `HTTP Status 400 (Bad Request)` が返ります。詳細は [削除ユーザー登録APIのレスポンス](#user-data-deletions-api-response) をご覧ください。

#### 削除ユーザー登録APIのペイロード例

##### 削除したいユーザーを登録する

```json
{
  "identity_type": "user_id",
  "identity_value": "user-123"
}
```



### 削除ユーザー登録APIのリクエスト

**リクエストヘッダー**

リクエストのヘッダーには、以下の値を設定します。

| ヘッダー | 説明 | 必須 |
| --- | --- | --- |
| Content-Type | application/jsonを指定します。 | 必須 |
| X-Repro-Token | [Repro API トークンの取得](#user-data-deletion-api-get-api-token) で取得したトークンを指定します。 | 必須 |

**リクエストボディ**

メッセージをJSONフォーマットで設定します。



### 削除ユーザー登録APIのレスポンス

**レスポンスヘッダー**

レスポンスのヘッダーには、以下の値が含まれます。

| ステータス | ヘッダー | 説明 |
| --- | --- | --- |
| 正常 | `X-RateLimit-Limit` | 単位時間あたりのアクセス上限 |
| 正常 | `X-RateLimit-Remaining` | アクセスできる残り回数 |
| 正常 | `X-RateLimit-Reset` | アクセス数がリセットされる時刻(unixtime) |
| リクエスト制限 | `Retry-After` | 再実行可能になるまでの秒数 |

**レスポンスボディ**

削除ユーザー登録APIをコールした際の、レスポンスに含まれるステータスコードとエラーメッセージの一覧は下記になります。

#### 202 Accepted

リクエストが成功しました。

レスポンスボディ:

```json
{
  "status": "accepted"
}
```

#### 400 Bad Request

リクエストにエラーがあります。タイプミスなどがないかご確認ください。

レスポンスボディ:

```json
{
  "error": {
    "messages": ["error message"]
  }
}
```

#### 401 Unauthorized

Repro API トークンが指定されていません。

レスポンスボディ:

```json
{
  "status": "unauthorized",
  "error": {
    "messages": [
      "Please include your Repro API Token as \"X-Repro-Token\" HTTP header."
    ]
  }
}
```

#### 403 Forbidden

指定した Repro API トークンが間違っています。

レスポンスボディ:

```json
{
  "status": "forbidden",
  "error": {
    "messages": [
      "Please check your Repro API Token as \"X-Repro-Token\" HTTP header."
    ]
  }
}
```

#### 404 Not Found

エンドポイントが存在しません。

レスポンスボディ:

```json
{
  "status": "not_found",
  "error": {
    "messages": [
      "Not found."
    ]
  }
}
```

#### 415 Unsupported Media Type

受理できないフォーマットのデータが含まれています。 リクエストヘッダの
`Content-Type` やエンドポイントに誤りがないか確認してください。

レスポンスボディ:

```json
{
  "error": {
    "messages": ["The provided content-type '指定されたMime Type' is not supported."]
  }
}
```

#### 429 Too Many Requests

リクエスト数が多すぎます。 `Retry-After` ヘッダーに記載された秒数待った後、リクエストを再開してください。

レスポンスボディ:

```json
{
  "status": "too_many_requests",
  "error": {
      "messages": [
          "Too many requests hit the API too quickly."
      ]
  }
}
```

### 削除が完了した時にメールを受信する

ユーザーの削除が完了すると、下記メールを受信します。



##### NOTE
- 指定したユーザーの削除工程がすべて完了した時に受信します。

---

## メール

* [配信前準備の概要](https://docs.repro.io/ja/dev/mail/getstarted.md)
  * [認証設定（迷惑メール対策）](https://docs.repro.io/ja/dev/mail/getstarted.md#id2)
  * [メール配信チャネルの作成](https://docs.repro.io/ja/dev/mail/getstarted.md#id3)
  * [メールアドレスのReproへの連携](https://docs.repro.io/ja/dev/mail/getstarted.md#repro)
  * [メール配信リストの整備](https://docs.repro.io/ja/dev/mail/getstarted.md#id4)
* [迷惑メール対策](https://docs.repro.io/ja/dev/mail/anti-spam.md)
  * [SPF、DKIM、DMARC認証について](https://docs.repro.io/ja/dev/mail/anti-spam.md#spfdkimdmarc)
  * [設定の流れ](https://docs.repro.io/ja/dev/mail/anti-spam.md#id2)
* [メールチャネル設定](https://docs.repro.io/ja/dev/mail/email-channel.md)
  * [メールチャネルの作成](https://docs.repro.io/ja/dev/mail/email-channel.md#id2)
  * [メールチャネルに対するメールアドレスの紐づけ](https://docs.repro.io/ja/dev/mail/email-channel.md#id4)
  * [キャンペーンでのチャネル指定](https://docs.repro.io/ja/dev/mail/email-channel.md#id5)
  * [よくあるご質問](https://docs.repro.io/ja/dev/mail/email-channel.md#id6)
* [Reproへのメールアドレス連携方法](https://docs.repro.io/ja/dev/mail/email-address-integration.md)
  * [管理画面からメールアドレスをインポートする](https://docs.repro.io/ja/dev/mail/email-address-integration.md#id1)
  * [CSV仕様](https://docs.repro.io/ja/dev/mail/email-address-integration.md#csv)
  * [S3アップロード](https://docs.repro.io/ja/dev/mail/email-address-integration.md#s3)
  * [よくあるご質問](https://docs.repro.io/ja/dev/mail/email-address-integration.md#id6)
  * [SDKを利用してメールアドレスをセットする](https://docs.repro.io/ja/dev/mail/email-address-integration.md#sdk)
* [配信リスト整備](https://docs.repro.io/ja/dev/mail/email-address-management.md)
  * [取り込むべきメールアドレス種別](https://docs.repro.io/ja/dev/mail/email-address-management.md#id2)
  * [インポート手順](https://docs.repro.io/ja/dev/mail/email-address-management.md#id3)
  * [インポートしたメールアドレスの状態を確認する](https://docs.repro.io/ja/dev/mail/email-address-management.md#id6)
* [メール配信のウォームアップ](https://docs.repro.io/ja/dev/mail/warmup.md)
  * [ウォームアップのやり方](https://docs.repro.io/ja/dev/mail/warmup.md#id2)

---

## 配信前準備の概要

Reproでメールを配信する前に、以下の設定を行っていただく必要があります。

### 認証設定（迷惑メール対策）

メールの到達率を向上させ、不正な送信を防ぐためにSPF、DKIM、DMARC認証を設定します。
詳細は [迷惑メール対策](https://docs.repro.io/ja/dev/mail/anti-spam.md) を参照してください。

### メール配信チャネルの作成

クーポンのお知らせ、キャンペーンのお知らせなど、複数の配信種別が存在する場合は、それぞれの種別ごとに購読者、購読解除者を連携する必要があります。Reproではこの配信種別をチャネルとして表現します。メールアドレス連携の前にチャネルを作成します。
詳細は [メールチャネル設定](https://docs.repro.io/ja/dev/mail/email-channel.md) を参照してください。

### メールアドレスのReproへの連携

メールを配信したいユーザーのメールアドレスをReproに連携します。
SDK、APIでのインポート、管理画面からのCSVアップロードでメールアドレス連携が可能です。
詳細は [メールアドレスのReproへの連携](https://docs.repro.io/ja/dev/mail/email-address-integration.md) を参照してください。

### メール配信リストの整備

メール配信前に、バウンス、オプトアウト等の配信停止リストをReproに連携していただく必要があります。
これにより、不達や不要なメール送信を防ぎ、配信品質を向上させることができます。
詳細は [メール配信リストの整備](https://docs.repro.io/ja/dev/mail/email-address-management.md) を参照してください。

---

## 迷惑メール対策

メールを確実に受信者に届けるために、ReproではSPF、DKIM、DMARC認証設定を必須としています。これらは、不正なメール送信を防ぎ、ドメインの信頼性を守る役割を果たします。このページではメール配信前におこなう認証設定の流れについて説明します。

### SPF、DKIM、DMARC認証について

| 認証方式 | 説明 |
| --- | --- |
| SPF（Sender Policy Framework） | 特定のドメインから送信するメールサーバーを許可する仕組み。不正なサーバーからのなりすましメールを防ぎます。 |
| DKIM（DomainKeys Identified Mail） | メールに電子署名を付与し、送信後の改ざんを防止します。 |
| DMARC（Domain-based Message Authentication, Reporting, and Conformance） | SPFとDKIMの設定が正しく行われているかを確認し、不正なメールの処理方法を決定するポリシーです。 |

### 設定の流れ

以下のステップで設定を行っていただきます。

1. Reproからお送りするヒアリングフォームへの回答
2. Reproから発行される設定値を利用ドメインに設定
3. ドメイン設定後の疎通確認メールの受信

#### Reproからお送りするヒアリングフォームへの回答

メールオプションのご契約時、Repro カスタマーサクセス または営業よりメール配信時に利用するドメインと、メールアドレス連携方法に関するヒアリングフォームをお送りします。設問項目に従いフォームの回答をお願いいたします。

#### Reproから発行される設定値を利用ドメインに設定

ヒアリングフォームの情報をもとに、送信者ドメインのDNSレコードに設定していただく内容をReproよりお送りします。利用しているDNSサービスの管理画面等から、送信ドメインのDNSレコードに対して設定していただきます。

##### NOTE
example.comはサンプルです。example.comに当たる部分にご利用いただくドメインが入ります。

**Reproよりお送りする設定値の例**

| ドメイン | DNSレコードタイプ | 設定値 |
| --- | --- | --- |
| rprmail.example.com | MX | "10 feedback-smtp.ap-northeast-1.amazonses.com" |
| rprmail.example.com | TXT | "v=spf1 include:amazonses.com ~all" |
| 1234rpr._domainkey.example.com | TXT | "p=aaaaaa" "bbbbb" |
| \_dmarc.example.com | TXT | "v=DMARC1; p=none;" |

##### NOTE
SPF、DKIM、DMARC認証への対応のため、ご利用ドメインのサブドメインに対して各種レコードの設定をしていただきます。
SPF認証のための rprmail サブドメインはデフォルトの指定値ですが、ご利用状況に合わせて変更が可能です。rprmail以外のサブドメインのご利用を希望の場合はご連絡ください。ただし、 example.com のようにサブドメインがない状態でのレコード設定はできません。

##### WARNING
**DKIM認証のためのTXTレコード設定値は1レコードに収めて設定してください**

TXTレコードはダブルクオートで囲まれた部分を1つの文字列とカウントします。また、1文字列あたりの文字数は255文字までとなっています。255文字以上の値をTXTレコードに設定したい場合は、半角スペースで複数の文字列を連結して設定する必要があります。

弊社からお渡しするDKIM認証のためのレコード設定値は255文字以上あるため、半角スペースで連結して1レコードに収めるようにしてください。同じホスト名でTXTレコードを2件以上作成して分割すると、DKIM認証ができません。

例: xxx._domainkey.yyy.jp. 3600 IN  TXT     "v=DKIM1; p=aaaaaa" "bbbbb"

#### ドメイン設定後の疎通確認メールの受信

ドメイン設定完了後、Reproにその旨を通知していただきます。Reproでの確認後、疎通確認メールをお送りします。

設定完了時、以下のようなツールで各ドメインの設定が正しく行われているかをご確認ください。

- [SPFレコード確認](https://powerdmarc.com/ja/spf-record-lookup/)
- [DKIMレコード確認](https://powerdmarc.com/ja/dkim-record-lookup/)
- [DMARCレコード確認](https://powerdmarc.com/ja/dmarc-record-checker/)

##### NOTE
認証設定が不十分な場合、メールが迷惑メールフォルダに振り分けられたり、配信自体がブロックされることがあります。

---

## メールチャネル設定

キャンペーン作成時は、どの配信カテゴリーとしてメールを送るかを指定する必要があります。Reproでは、この配信カテゴリーをチャネルとして管理します。メール配信を始める前に、利用するチャネルをあらかじめ作成してください。

##### NOTE
複数の配信カテゴリーを使い分けない場合でも、チャネルの指定は必須です。
メールの利用開始時には、どのプロジェクトにも「全てのユーザー」チャネルがあらかじめ作成されています。
配信を分ける必要がない場合は、「全てのユーザー」チャネルを利用してください。

### メールチャネルの作成

管理画面にログインし、サイドメニューから[設定] > [メール設定] > [メールチャネル設定] をクリックします。



配信したい内容に応じて、クーポンのお知らせ、キャンペーンのお知らせなどの単位で [新規作成] からチャネルを作成してください。

#### 「全てのユーザー」チャネル

メールの利用開始時には、「全てのユーザー」チャネルがあらかじめ作成されています。既に登録済みのメールアドレスは、「全てのユーザー」チャネルの購読状態として登録されています。
また、メールアドレスをチャネルに紐づけてインポートした場合、その情報は指定したチャネルに加えて「全てのユーザー」チャネルにも反映されます。
例えばチャネルAを指定してメールアドレスCSVをアップロードした場合、チャネルAと「全てのユーザー」チャネルの2つにCSVの内容が反映されます。
ただし、「全てのユーザー」にも反映されるのは、対象となるユーザーが「全てのユーザー」チャネルに対する購読情報が存在しない時のみです。

### メールチャネルに対するメールアドレスの紐づけ

複数の配信カテゴリーを利用してメールを配信する場合は、どのユーザーがどのチャネルを購読しているかをReproに連携する必要があります。
管理画面からのCSVアップロード、またはS3へのCSVアップロード時に、メールアドレスをチャネルに紐づけて連携できます。
なお、新しくチャネルを作成した場合、すでにReproに登録済みのメールアドレスであっても、そのチャネルの配信対象として利用するには、当該チャネルに紐づけて再度インポートする必要があります。

詳細は [メールアドレスのReproへの連携](https://docs.repro.io/ja/dev/mail/email-address-integration.md) を参照してください。

### キャンペーンでのチャネル指定

メールキャンペーンの作成時には、送信に利用するチャネルを指定します。
選択したチャネルを購読しているユーザーのみが配信対象になります。
詳細は [メールキャンペーン作成](https://docs.repro.io/ja/dashboard/campaign/mail/broadcast-mail.md) を参照してください。

### よくあるご質問

#### SDKからのメールアドレス登録時、メールアドレスが紐づくチャネルを指定することはできますか？

指定ができません。メールアドレス登録時は「全てのユーザー」チャネルにメールアドレスが紐づくように登録されます。
追加でチャネルに紐づくよう設定をしたい場合は、管理画面からのCSVアップロードまたはS3からのアップロードをご利用ください。
SDKからユーザーがどのチャネルを購読または購読解除するかを指定するAPIは2026年中を目途に追加予定です。

---

## Reproへのメールアドレス連携方法

メールを配信したいユーザーのメールアドレスをReproに連携する方法は3つあります。
用途に合わせて後述する手順を参照し、メールアドレスを連携してください。

| 連携方法 | 概要 | 用途 |
| --- | --- | --- |
| 管理画面からCSVをアップロードする | Reproの管理画面からメールアドレスリストをCSVファイルとしてアップロードします。 | Reproのメール利用開始時の一括取り込み、CDPや自社基盤で抽出したメールアドレスの取り込み等 |
| S3へアップロードする | Reproの提供するAWS S3 bucketに対してメールアドレスリストをCSVファイルとしてアップロードします。 | CDPや自社基盤で保有しているメールアドレスの継続的取り込み |
| SDK(iOS/Android/Web)経由でセットする | SDKでユーザープロフィールとしてメールアドレスをセットします。 | アプリやサービスでメールアドレスを取得した際の取り込み |

### 管理画面からメールアドレスをインポートする

#### メール配信用ユーザー情報インポート画面に遷移

管理画面にログインし、サイドメニューから[設定] > [メール設定] > [メール配信用ユーザー情報インポート] をクリックします。



#### メールアドレスをインポートする

CSVファイルをインポート > [ファイルを選択]をクリックし、インポート種別を選択してメールアドレスをインポート出来ます。
インポート時は後述するCSV仕様に基づいて作成したCSVを選択してください。



| 取り込み種別 | 説明 | 配信可否 |
| --- | --- | --- |
| 配信可能ユーザーとしてメールアドレスをインポート | メールの配信対象として、オプトインされたメールアドレスをインポートできます | 行われる |
| 購読解除ユーザーとしてメールアドレスをインポート | Webサイトやアプリで購読解除したメールアドレスをインポートできます | 行われない |
| 配信停止ユーザーとしてメールアドレスをインポート | 購読解除やバウンス以外の理由で配信を行いたくないメールアドレスをインポートできます | 行われない |
| バウンスユーザーとしてメールアドレスをインポート | 存在しないアドレスなど、ハードバウンスしたメールアドレスをインポートできます | 行われない |

#### メールチャネルの指定

どのチャネルに対してメールアドレスおよびユーザーIDを紐づけるかを指定するために、チャネルを選択します。

##### NOTE
「全てのユーザー」以外のチャネルを指定してCSVをインポートした場合、「全てのユーザー」チャネルに対しても情報が紐づけられます。
ただし、「全てのユーザー」にも情報が紐づけられるのは、対象となるユーザーが「全てのユーザー」チャネルに対する購読情報が存在しない時のみです。



#### すでに Repro に存在するユーザーIDをインポートした場合

Reproにすでに存在するユーザーIDがインポートするメールアドレスリストに含まれている場合、Reproにすでに存在するユーザーのステータスを維持するか、インポート時のステータスで上書きするかを選択できます。

例）

| Reproのステータスを維持する | 取り込み種別 | 取り込み前のユーザーのステータス | 取り込み後のユーザーのステータス |
| --- | --- | --- | --- |
| チェックする | 配信可能ユーザーとしてインポート | バウンスユーザー | バウンスユーザー |
| チェックしない | 配信可能ユーザーとしてインポート | バウンスユーザー | 配信可能ユーザー |

ステータスを維持したい場合、「Reproのステータスを維持する」チェックを入力してください。「Reproのステータスを維持する」を選択した際は、配信可能ユーザーとしてインポートのみが選択可能になります。

### CSV仕様

アップロードするCSVの詳細を記載します。

#### CSVフォーマット

```
user_id,email_address
123456,aaaa@example.com
234567,jjjj@example.com
```

取り込み種別によって必須カラムが変わります。

| 取り込み種別 | 必須カラム | 任意カラム |
| --- | --- | --- |
| 配信可能ユーザー | `user_id` 、 `email_address` | なし |
| 購読解除ユーザー | `email_address` | `user_id` |
| 配信停止ユーザー | `email_address` | `user_id` |
| バウンスユーザー | `email_address` | `user_id` |

##### WARNING
**新規のメールアドレスを登録する場合、必ずユーザーIDとセットでインポートしてください。**

- 登録されたことのないメールアドレスをユーザーIDなしでインポートすると、内部的にユーザーIDが設定されていないユーザーが作成されます。
- 後続のインポート時にメールアドレスに対して改めてユーザーIDが設定されると、ユーザー情報が繋がらずに [「Reproのステータスを維持する」を選択](#already-imported-user-id) しても、事前のステータスを正しく紐づけられません。

- アップロード可能なCSVファイルは最大500MBです。
- CSVファイルの文字コードはUTF-8のみ利用可能。ファイル中に日本語などを含みUTF-8以外で保存されているとアップロード時にエラーとなります。
- 以下のケースは「不正なCSVファイル」としてアップロード時にエラーとなります。
  - 別のファイルの拡張子を `.csv` にしただけのような不正なファイル
  - UTF-8で解釈出来ない文字が記述されている。
  - 必須のカラムがCSVヘッダー(1行目)に記述されていない。
  - 同じカラムがCSVヘッダーに複数存在する。
- メールアドレスが空の場合、あるいはメールアドレスの形式が不正な場合はアップロードに成功しますがその後インポートに失敗した旨のエラーメールが送信されます。
- インポート時のエラーログは以下のような内容の CSV ファイルとしてダウンロードすることができます。

```
user_id,email_address
has_error_mail_address,CSVの書式が正しくありません、不正なダブルクォーテーションが使われています
```

### S3アップロード

Reproの提供するAWS S3 bucketに対してCSVファイルをアップロードすることで、メールアドレスの登録を行うことができます。

##### NOTE
利用する際には、Reproの提供するAWS S3 bucketに対してオブジェクトをアップロードするための認証情報を事前に発行する必要があります。詳細については [こちら](https://docs.repro.io/ja/dev/user-profile-bulk-import-api/index.md#user-profile-bulk-import-s3) の項目をご確認ください。

アップロードするS3 bucket、パスについては、[設定] > [メール設定] > [メール配信用ユーザー情報インポート] から確認することができます。

##### WARNING
アップロードするCSVファイルは、名前に `/` 及び空白文字を含めることはできません。
アップロードするCSVファイルは、500MBまでのサイズである必要があります。

例として、AWS CLIを利用した場合には以下のようなコマンドでメールアドレスの記載されたCSVをS3にアップロードできます。
`<EMAIL_CHANNEL_ID>` の部分は [設定] > [メール設定] > [メールチャネル設定] の該当チャネルに表示されているチャネルIDを指定してください。
また `<YOUR_APP_ID>` の部分は管理画面に記載されているものをお使いください。 `(insert|subscribe|unsubscribe|stopped|bounced)` の部分は、取り込みオペレーションを1種類のみ指定してください。

取り込みオペレーションと挙動は以下のようになります。
すでに Repro に存在するユーザーIDをインポートした場合の挙動は [こちら](#already-imported-user-id) の例も参照ください。

|  | 取り込み種別 | 説明 | すでにReproに存在するユーザーIDを取り込んだ場合 |
| --- | --- | --- | --- |
| insert | 配信可能ユーザー | メールの配信対象として、オプトインされたメールアドレスをインポートできます | すでにReproに存在するユーザーのステータスを維持します |
| subscribe | 配信可能ユーザー | メールの配信対象として、オプトインされたメールアドレスをインポートできます | 配信可能ユーザーに上書きされます |
| unsubscribe | 購読解除ユーザー | Webサイトやアプリで購読解除したメールアドレスをインポートできます | 購読解除ユーザーに上書きされます |
| stopped | 配信停止ユーザー | 購読解除やバウンス以外の理由で配信を行いたくないメールアドレスをインポートできます | 配信停止ユーザーに上書きされます |
| bounced | バウンスユーザー | 存在しないアドレスなど、ハードバウンスしたメールアドレスをインポートできます | バウンスユーザーに上書きされます |
```
$ export AWS_ACCESS_KEY_ID=AKIAXXXXXXX
$ export AWS_SECRET_ACCESS_KEY=XXXXXX
$ aws s3 cp user_profiles.csv s3://repro-data-store/<YOUR_APP_ID>/email_address/:year/:month/:day/(insert|subscribe|unsubscribe|stopped|bounced)/<EMAIL_CHANNEL_ID>/mail_address.csv
```

### よくあるご質問

#### ファイルのアップロードが完了したかはどのように知ることができますか？

インポート処理が完了すると、インポートしたメールアドレスファイルの情報を記載した通知メールが送信されます。エラーが発生した場合は、エラー用CSVファイルのダウンロードリンクも合わせて記載されます。

#### S3パスに含まれる year、month、dayはいずれも指定が必須ですか？

全て指定が必須です。ファイルアップロード日を yyyy/mm/dd（例：2025/04/30） 形式で指定するようにしてください。

#### S3へのアップロード中、さらに別のファイルをアップロードすることは可能ですか？

可能です。並行して複数ファイルのアップロードができます。
ただし、S3パスとファイル名が同じ場合、最初にアップロードしたデータが処理されず最後にアップロードしたデータが複数回処理されることがあります。同日に同名のファイルをアップロードしたい場合は、各ファイル名を変更することを推薦します。

#### 同一ユーザーに対して違うメールアドレスを設定して取り込んだ場合、そのユーザーのメールアドレスはどのように設定されますか？

メールアドレスは最後に取り込まれたものが反映されます。例えば以下のような2行があるファイルをとりこんだ場合、 `user-01` のメールアドレスは `mail-address-02@example.com` になります。

```
user-01,mail-address-01@example.com
user-01,mail-address-02@example.com
```

### SDKを利用してメールアドレスをセットする

iOS/Android SDK、Web SDKから標準ユーザープロフィールとしてユーザーのメールアドレスをセットすることで、一斉配信メールの配信に利用できます。
各SDKの設定方法の詳細は以下を参照してください。

- [iOS/Android SDK](https://docs.repro.io/ja/dev/sdk/user-profile.md#standard-user-profile)
- [Web SDK](https://docs.repro.io/ja/dev/web/user-profile.md#web-standard-user-profile)

---

## 一斉配信メール

一斉配信メールは、任意の配信対象にメールを一斉送信する機能です。
例えば、ECサイトにおいてカートに追加したユーザーが、1日後に商品を購入していない場合にメールで購入を促すことが出来ます。

### メールアドレスのインポート

配信前の事前準備として、メールを配信したいユーザーのメールアドレスをReproにインポートする必要があります。事前準備は [Reproへのメールアドレスの連携](https://docs.repro.io/ja/dev/mail/email-address-integration.md) を参照してください。

### 一斉配信メールを作成する

#### 一斉配信メール作成画面に遷移

管理画面にログインし、サイドメニューから[マーケティング]  > [メール] をクリックします。



メール一覧画面から、[新規作成] > [一斉配信メール]をクリックします。



一斉配信メール作成画面が表示されます。



#### キャンペーン情報を入力

キャンペーンの名前とキャンペーンのゴール、キャンペーンの狙いと実施後の結果を入力します。 （キャンペーンのゴールとキャンペーンの狙いと実施後の結果は任意です）



| キャンペーン名 | 一斉配信メールの名前を記入します |
| --- | --- |
| キャンペーンのゴール | ゴールとなるイベントを選択します |
| キャンペーンの狙いと実施後の結果 | キャンペーンの狙いと結果を記入します。管理者向けのメモとして利用できます |

#### 配信対象設定を入力

キャンペーンの配信対象を指定します。フィルターを利用して、配信対象となるユーザーを絞り込めます。
あわせて、配信に利用するチャネルを選択します。
選択したチャネルを購読しているユーザーにのみ配信されます。対象チャネルを一度も購読していないユーザーや、すでに購読解除しているユーザーには配信されません。



配信対象設定の詳細は [配信対象設定](https://docs.repro.io/ja/dashboard/campaign/push-notification.md#push-measurement-filter) を参照してください。

##### 対象ユーザー数と配信可能ユーザー数

対象ユーザー数はReproに登録されているユーザーの中で条件に合致しているユーザー数の概算です。
配信可能ユーザー数は対象ユーザーのうち、指定されたチャネルで配信可能なメールアドレスが設定されているユーザーの数です。メールアドレスが登録されていない、バウンスアドレスや該当チャネルでは購読解除されているなど、配信可能なメールアドレスが設定されていないユーザーは配信可能ユーザー数に入りません。

##### 購読解除しているユーザーにも配信する



「購読解除しているユーザーにも配信する」にチェックを入れると、配信可能なユーザーに加えて、選択したチャネルを購読解除しているユーザーにも配信できます。
配信可能ユーザーなどのユーザー種別詳細は [配信リスト整備](https://docs.repro.io/ja/dev/mail/email-address-management.md) を参照してください。

配信停止、バウンスユーザーは購読解除しているユーザーに含まれないため、チェックを入れていても配信が行われません。

##### NOTE
「購読解除しているユーザーにも配信する」を選択していても、対象チャネルの購読状態が一度も登録されていないユーザーには配信されません。

##### WARNING
購読解除済みのユーザーにもメールが配信できるため、特定電子メール法、個人情報保護法、その他関連法令を遵守した上で利用してください。

以下のようなサービス利用に際して必須の情報を配信するメールでの利用を想定しています。

- 重要なお知らせ（サービスの障害、規約変更など）

以下のような広告・販促を主目的とするメールを送信する場合は、チェックを入れないようにしてください。

- 商品・サービスの購入を促す内容
- キャンペーン、セール、クーポン等の案内
- 利用促進・再訪問を目的としたマーケティングメッセージ

送信内容が「広告または販促」に該当するかの最終的な判断および責任は、利用者に帰属します。

#### 配信設定を入力

配信設定として、配信時刻や定期配信・即時配信の設定を行います。



##### 指定された時刻に配信

指定した時刻にメールを一斉配信できます。
配信頻度は、一度だけ、毎日、毎週、毎月から指定します。

###### 一度だけ配信する

配信日時を指定し、1度だけ配信できます。
現在時刻より、過去の日付や、15分以内の配信時刻は設定できません。



###### 毎日配信する

配信期間と配信時刻を指定し、毎日メールを一斉配信できます。
以下の例では、2024年8月1日から8月31日まで毎日9時にメールが一斉配信されます。
また、 `終了日を指定しない` にチェックを入れた場合はキャンペーンが非公開(停止)状態にされるまで配信されます。



###### 毎週配信する

配信期間と配信曜日、配信時刻を指定し、毎週メールを一斉配信できます。
以下の例では、2024年8月1日から8月31日まで毎週月曜日(8月5日、8月12日、8月19日、8月26日)の9時にメールが一斉配信されます。
また、 `終了日を指定しない` にチェックを入れた場合はキャンペーンが非公開(停止)状態にされるまで配信されます。



###### 毎月配信する

配信期間と毎月何日に配信するか、配信時刻を指定し毎週メールを一斉配信できます。
以下の例では、2024年1月1日から2024月12月1日まで毎月1日の9時にメールが一斉配信されます。
また、 `終了日を指定しない` にチェックを入れた場合はキャンペーンが非公開(停止)状態にされるまで配信されます。



#### 差出人設定を入力

メールの差出人の設定を行います。
メールアドレスのドメインは、一斉配信メールのお申し込みの際にReproで対応します。



| 差出人メールアドレス | メールの差出人メールアドレスに表示されます |
| --- | --- |
| 差出人名 | メールの差出人名に表示されます |
| 返信メールアドレス | メールを受け取ったユーザーから返信を受け取る場合、差出人メールアドレスとは別のメールアドレスで受け取りたい場合に記入してください。 返信用メールアドレスの設定がない場合は、差出人メールアドレスが返信先として設定されます |

#### コンテンツを入力

メールの件名や本文を入力し、プレビューで内容を確認できます。
作ったメールはテスト配信で実際の表示を確認することも可能です。

| 件名 | 記入した内容が、メールの件名に表示されます |
| --- | --- |
| プレヘッダー | メーラーの一覧画面に表示される本文の先頭行を、このフィールドで記入した内容に差し替えることができます |
| HTMLメール | メール用のHTML/CSSを画面操作で作成することができます |
| テキストメール | 記入した内容がテキストメールの本文に表示されます。なお、テキストメールだけでの配信はできません |
| テスト配信 | 記入したメールアドレスへメールを配信します。カンマ区切りで複数のメールアドレスに送信することができます |

##### スタンダード

画面操作で本文を作成することができます。見出し、画像、ボタンなどをドラッグアンドドロップで配置可能です。



##### カスタム

メール用のHTML/CSSを直接入力して本文を作成することができます。お持ちのHTML/CSSをこちらに貼り付けてください。



###### カスタムエディタでの画像追加

HTML内に画像を挿入したい場合、画像を追加したい箇所にカーソルを移動し `画像を追加` をクリックしてください



画像を選択すると、アップロードした画像が指定されたimg要素がカーソル位置に追加されます。
アップロードした画像が崩れる場合は必要に応じてCSSを編集してください。



##### 購読解除URLの挿入

Reproが提供する購読解除URLを利用できます。 `{{ unsubscribe_url }}` を本文中に記載すると、 `https://email.repro.io/unsubscribe/xxxxx` のような購読設定の変更に利用できるURLがメール本文に挿入されます。
メールを受け取ったユーザーがURLから購読解除を行った場合は、そのメールが配信されたチャネルの購読状態が解除されます。

##### テスト配信

入力した件名、プレヘッダー、本文の表示確認のために、任意のメールアドレスにテスト配信することができます。テスト配信を行うメールアドレスはカンマ区切りで複数指定可能です。



##### NOTE
テスト配信機能では、Liquidを活用したパーソナライズ機能はご利用いただけません。 `{{ user_profile['name'] }}` のようなLiquidを含むメールをテスト配信機能を使って配信した場合、Liquid構文がそのまま配信されます。パーソナライズ機能の動作確認は、キャンペーンを公開した上でテスター向けに配信を行ってください。

#### 下書きで保存、非公開、公開



| 下書きで保存 | 作成途中の場合、下書き保存できます |
| --- | --- |
| 非公開 | 一斉配信メールを非公開状態で保存します。 非公開状態の場合、配信設定した時刻になっても一斉配信メールは配信されません |
| 公開 | 一斉配信メールが公開(配信中)となり、配信設定で指定した時刻にメールが配信されます |

##### 配信のリトライについて

* 一時的なエラーで配信が失敗した場合、1時間ごとの定期処理で最大12時間後までリトライされます

### 効果測定

メールの開封数やコンバージョン数といった、一斉配信メールの配信結果を確認できます。



#### ユニークユーザー数

ユニークユーザー数タブでは、配信結果にある項目をユーザー単位で集計した数値を表示します。

| 配信数 | メール配信サービスにリクエストが受理された数を表示します |
| --- | --- |
| 配信完了数 | 受取人のメールサーバーに正常にメール配信できた数を表示します |
| エラー数 | ハードバウンス等の理由で配信を行わなかったメールの合算値を表示します **ハードバウンスとは** メールアドレスが存在しない、受信者側のメールを拒否しているなど、次回以降届く見込みがないメールアドレスのことを指します。 |
| 開封数 | 配信から1週間以内に開封したユニークユーザ数を表示します |
| 開封率 | 開封率を表示します `開封数 / 配信完了数` で計算されます。 |
| リンククリック数 | メールに含まれたURLを1つでもクリックしたユニークユーザ数を表示します |
| CV数 | 開封から24時間以内にコンバージョンしたユニークユーザ数を表示します |
| CV率 | コンバージョン率を表示します |

#### 総回数

総回数タブでは、配信結果を集計した数値を表示します。

| 配信数 | メール配信サービスにリクエストが受理された数を表示します |
| --- | --- |
| 配信完了数 | 受取人のメールサーバーに正常にメール配信できた数を表示します |
| エラー数 | ハードバウンス等の理由で配信を行わなかったメールの合算値を表示します |
| 開封数 | 配信から1週間以内に開封した数を表示します |
| 開封率 | 開封率を表示します `開封数 / 配信完了数` で計算されます。 |
| リンククリック数 | メールに含まれたすべてのURLのクリック数の合計を表示します ※遷移先のURLが同じでもクエリパラメータが違う場合は違うURLとして計測されます |
| CV数 | 開封から24時間以内にコンバージョンした数を表示します |
| CV率 | コンバージョン率を表示します |

#### 注意事項

* エラー数が時間の経過とともに増えることがあるため、それに伴って配信完了数も減ることがあります。

##### セキュリティシステムやメーラーが一部の効果測定値に与える影響

Reproの一斉配信メールにおいて、ユーザーが利用しているセキュリティシステムやメーラー側の仕組みで実際にユーザーがメールの開封やクリックを発生させていない場合でも開封やクリックが計測されることがあります。

具体的には以下のようなケースが該当します。

* 画像の自動読み込み
  - Gmail等のメーラーの先読み機能でプロキシサーバーによって、メールがユーザーの受信箱に入った時点で画像ファイルを読み込む際に開封として扱われることがあります。
* セキュリティチェック
  - メーラーや、企業に導入されているセキュリティシステムがメール内のリンクに対してチェックをした際に開封やクリックが計測されることがあります。

### メール一覧画面

メール一覧画面では、作成された一斉配信メールとトリガーメールの概要とステータスが確認できます。

| 項目 | 説明 |
| --- | --- |
| ステータス | キャンペーンのステータスを表示します |
| キャンペーン名 | キャンペーン名とコンテンツの件名を表示します |
| キャンペーンのゴール | 設定したキャンペーンのゴールを表示します |
| 配信数 | ユーザーに対して配信したユニークな配信数の合計を表示します **配信数のカウント** 1日の間に同一ユーザーに複数回配信した場合でも1通としてカウントされます 同一ユーザーに日をまたいで2回配信した時は2通としてカウントされます |
| 配信完了数 | 配信数のうち、エラーが発生せずに配信された数を表示します |
| 開封 | 開封率と開封数を表示します |
| CV | コンバージョン数を表示します |
| 配信開始 | メールが配信開始された日時を表示します |
| 配信終了 | メールの配信期間が終了した日時を表示します |
| 設定アイコン | キャンペーンのステータスによって表示されるアイコンが異なります |

#### キャンペーンの検索

キャンペーン名や、タイプ、ステータスを元にメールのキャンペーンを検索できます。



##### キャンペーン名で検索

キャンペーン名を入力すると部分一致で検索できます。
件名やコンテンツを含めた検索をすることはできません。

##### タイプやステータスでの絞り込み

###### タイプによる絞り込み

一覧を一斉配信のみ絞り込みたい場合は `一斉配信` にチェックを入れ、「適用」ボタンをクリックするとキャンペーンを 一斉配信メールのみに絞り込みできます。

###### ステータスによる絞り込み

ステータスを指定して、キャンペーンを絞り込みできます。
絞り込みたいステータスにチェックを入れて、「適用」ボタンをクリックすることで指定したステータスのみに絞り込み出来ます。

* 配信中
* 配信予約
* 停止中
* 終了
* アーカイブ
* 下書き

### Liquidによるパーソナライズ機能

Liquidを活用すれば、一斉配信メールでユーザープロフィールを変数として差し込み、メッセージの内容をパーソナライズできます。
利用方法の詳細は [Liquidを活用したパーソナライズ](https://docs.repro.io/ja/dashboard/campaign/liquid-personalization.md) を参照してください。

---

## 配信リスト整備

メール配信前に、バウンス、オプトアウト等の配信停止リストをReproに連携していただく必要があります。これにより、不達や不要なメール送信を防ぎ、配信品質を向上させることができます。

### 取り込むべきメールアドレス種別

| Repro上での取り込み種別 | 説明 | 配信可否 |
| --- | --- | --- |
| 配信可能ユーザー | 現在メールを正常に送信できる状態のユーザーのメールアドレス。購読解除・バウンス・配信停止に該当しないもの。 | 行われる |
| 購読解除ユーザー | Webサイトやアプリ設定、配信されたメールから購読解除（オプトアウト）を行ったユーザーのメールアドレス | 行われない |
| バウンスユーザー | メールアドレスやドメインが存在せず恒久的なエラー状態のメールアドレス | 行われない |
| 配信停止ユーザー | 上記以外の理由でメール配信を行わないほうがよいユーザーのメールアドレス | 行われない |

##### NOTE
Reproでメールアドレスを取得しているユーザーがすでに退会済みの場合でも、Reproからメールが送信されます。退会ユーザーにつきましては、退会ユーザーを表すユーザープロフィールをSDKやユーザープロフィールAPIから付与した上で、配信対象から外すことを推奨いたします。

### インポート手順

各取り込み種別ごとのメールアドレスのインポート方法手順やCSVファイル仕様の詳細は [メールアドレスのReproへの連携](https://docs.repro.io/ja/dev/mail/email-address-integration.md) を参照してください。

#### バウンスユーザー

バウンスユーザーのメールアドレスはメール配信用ユーザー情報インポートから、ファイルを選択 >「バウンスユーザーをインポート」をクリックしてインポートできます。



#### 購読解除ユーザー

配信停止ユーザーのメールアドレスはメール配信用ユーザー情報インポートから、ファイルを選択 >「配信停止ユーザーをインポート」をクリックしてインポートできます。



### インポートしたメールアドレスの状態を確認する

インポートしたメールアドレスの状態が正しく更新されているか以下の手順で確認します。

#### 配信停止ユーザーの確認

メールアドレスをインポートした後、設定 > メール設定 > メールアドレス一覧にアクセスします。
左上にあるフィルターボタンをクリックし、停止フラグの `Stop` にチェックを入れてください。
自動的に一覧が更新されるので、インポートしたメールアドレスが含まれているか、ステータスが「配信不可」になっているか確認します。

#### バウンスユーザーの確認

メールアドレスをインポートした後、設定 > メール設定 > メールアドレス一覧にアクセスします。
左上にあるフィルターボタンをクリックし、停止フラグの `Bounce` にチェックを入れてください。
自動的に一覧が更新されるので、インポートしたメールアドレスが含まれているか、ステータスが「配信不可」になっているか確認します。

---

## メール配信のウォームアップ

Reproでのメール施策を開始する際、メール配信のウォームアップを行っていただく必要があります。
突如大量の配信を行うと、迷惑メールとみなされたり配信遅延が発生することがあります。最初は少量の配信数からスタートし、最大送信数に達するまで徐々に配信数を増やしていく活動（ウォームアップ）を行うことで、迷惑メールとみなされたり配信遅延が発生することを防ぎます。

##### NOTE
Repro以外の配信ツールで恒常的に配信していたとしても、Reproでメール配信を初めて行う場合はウォームアップが必要です。

##### NOTE
複数の送信ドメインを使い分けてメール配信を行う場合、送信ドメインごとにウォームアップを行ってください。

### ウォームアップのやり方

ウォームアップを行う前に、配信計画を立てる必要があります。ウォームアップ計画に基づくスケジュールで配信を行ってください。

#### ウォームアップ計画

1000通程度の配信からスタートし、1日ごとに段階的に送信数を増やしていき、最大送信数に達するまでウォームアップを行っていただくことをお勧めします。

以下は一例です。想定送信規模に応じて調整してください。

##### 最大で200万通を送信したい場合のウォームアップ計画の例

| 日数 | 送信数（通） |
| --- | --- |
| 1 | 1,000 |
| 2 | 2,000 |
| 3 | 5,000 |
| 4 | 10,000 |
| 5 | 20,000 |
| 6 | 40,000 |
| 7 | 80,000 |
| 8 | 100,000 |
| 9 | 150,000 |
| 10 | 200,000 |
| 11 | 250,000 |
| 12 | 400,000 |
| 13 | 600,000 |
| 14 | 1,000,000 |
| 15 | 2,000,000 |

#### ウォームアップ完了後

ウォームアップ完了後は、少なくとも1週間に1度から2週間に1度程度の頻度で、継続的にメール配信を行うようにしてください。長期間メール配信が行われないと、配信が行われなくなったものとみなされます。
もし1か月程度メール配信が行われなかった場合は、再度ウォームアップしていただくことを強く推奨します。

---

## ニュースフィード

ニュースフィードとは、**ユーザーごとのキャンペーンの配信履歴** のことです。この履歴を利用することで、今までに送ったキャンペーンの履歴をアプリ内のお知らせ欄などに表示することが可能です。

### 具体的なユースケース

* メッセージで配信したクーボンやシークレットセール情報などを見逃してしまった方でも後から情報を確認することができます。
* プッシュ通知でお知らせした注目記事を一覧として見せることで、ユーザーがサービスに戻ってきたときの体験向上や、記事回遊率を引き上げる効果が期待されます。

### 利用可能なチャネル一覧

* プッシュ通知
* アプリ内メッセージ
* Webメッセージ

##### WARNING
ニュースフィードと [Liquidによるパーソナライズ](https://docs.repro.io/ja/dashboard/campaign/liquid-personalization.md) は併用できません

### プッシュ通知でニュースフィードを有効にする

設定方法は [プッシュ通知 > キャンペーン](https://docs.repro.io/ja/dashboard/campaign/push-notification.md#push-campaign) の項目「通知をニュースフィードとして使う」をご覧ください

### アプリ内メッセージでニュースフィードを有効にする

設定方法は [アプリ内メッセージ > キャンペーンをニュースフィードとして利用するかを指定](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md#in-app-message-newsfeed) をご覧ください。

### Webメッセージでニュースフィードを有効にする

設定方法は [Webメッセージ > キャンペーンをニュースフィードとして利用するかを指定](https://docs.repro.io/ja/dashboard/campaign/web-message.md#web-message-newsfeed) をご覧ください。

### 利用方法

ご利用に際しては、アプリ側で実装が必要になります。詳細は [開発ガイド > iOS/Android SDK > ニュースフィード](https://docs.repro.io/ja/dev/sdk/newsfeed.md) をご覧ください。

また、ニュースフィードAPIを使用して取得することも可能です。ニュースフィードAPIの詳細は [開発ガイド > ニュースフィードAPI](https://docs.repro.io/ja/dev/newsfeed-api/index.md) をご覧ください。

---

## Webメッセージ

WebメッセージはWebサイトを閲覧中の特定のユーザーに対し、適切なタイミングで画像やボタンのついたカスタマイズ可能なメッセージをポップアップで表示できる機能です。管理画面でメッセージを登録するだけで、既にリリースされたWebサイトにメッセージを配信することができます。そのため、マーケターだけでコンバージョンを上げるためのキャンペーンを配信することができます。

  

以下の設定をカスタマイズすることで、エンドユーザーの行動に即した効果的なマーケティング施策を実行することができます。

- 画像
- Webサイト上のLPを開くためのURLや、Webメッセージからアプリを起動し、アプリ内の任意の画面に遷移するためのディープリンクを埋め込めるボタン（1-4個設定可能）
- スケジュール
- 配信対象となるユーザー
- メッセージ表示タイミング

例えば:

- カートに商品を入れたあと購入に至らなかったユーザーに対しクーポンを配信する
- コンバージョンをあげるために、数日前に登録したユーザーに適切なナビゲーションを表示する

また、作成されたWebメッセージはキャンペーン毎に1ユーザーに対して1回、もしくは複数回メッセージを表示することができます。表示回数については、配信設定で設定できます。なお、Webメッセージは画面上に表示されたタイミングで既読したとみなし、各種計測結果に反映されます。

### Webメッセージを作成する

管理画面を開いて以下を実行してください。

**マーケティング > メッセージ** に行き、 新規作成ボタンから **Webメッセージ** をクリックしてください。



##### WARNING
サイトのソースコード上でmeta要素 での `viewport` の 設定次第で、いずれのメッセージテンプレートにおいても意図通りに表示されない可能性があります。
 
意図通りに表示されない場合は、`viewport` の設定もの変更もしくは、カスタムメッセージをご利用いただきWeb メッセージの設定を変更していただく必要があります。
 
ご不明点がございましたら、チャットサポートまでご連絡ください。
 

#### メッセージテンプレートの選択

テンプレート選択画面からどのタイプのメッセージを作るかを決めます。メッセージのタイプは **ダイアログ** 、**固定バー** 、**吹き出し** 、**埋め込み** 、**その他** の5タイプがあり、ボタンやテキスト、画像の有無別にテンプレートが用意されています。使用するテンプレートの画像をクリックすると、メッセージの編集画面へと遷移します。

- テキスト　: メッセージに見出しと本文が含まれます
- 画像　　　: メッセージに画像を添付できます
- ボタン　　: 任意のテキストのボタンを設置できます。ボタンのクリックイベントはその他のイベント同様、トラックすることができます。





#### キャンペーン設定

メッセージの効果を測るため、キャンペーン名とコンバージョンゴールを設定します。



##### キャンペーン名

キャンペーン名を設定します。メッセージの一覧に表示されます。

##### コンバージョンイベントを指定

キャンペーンのゴールとなるイベントを最大2つまで指定できます。Webメッセージが表示されてから24時間以内にこれらのイベントを実施したユーザーの数が集計されます。詳細は [こちら](#web-message-measurement) をご覧ください。詳細は [ニュースフィード](https://docs.repro.io/ja/dashboard/campaign/newsfeed.md) をご覧ください。



###### キャンペーンをニュースフィードとして利用するかを指定

上記の画像にある「通知をニュースフィードとして使う」のチェックボックスを使い、キャンペーンをニュースフィードとして利用するかを指定します。

ニュースフィードとは、**ユーザーごとのキャンペーンの配信履歴** のことです。この履歴を利用することで、今までに送ったキャンペーンの履歴をアプリ内のお知らせ欄で表示するといったことが可能です。

ご利用に際しては、ニュースフィードAPIを使用して取得可能です。詳細は [開発ガイド](https://docs.repro.io/ja/dev/newsfeed-api/index.md) をご覧ください。

またWeb SDKに加えて、Native SDKもご利用されている場合は、SDKを使用しても取得が可能です。この場合、アプリ側で実装が必要になります。詳細は [開発ガイド](https://docs.repro.io/ja/dev/sdk/newsfeed.md) をご覧ください。

##### WARNING
アプリ内メッセージおよびWebメッセージをニュースフィードとして利用する際には、仕様上下記のようなユースケースでは意図した挙動とならないことがございますのでご注意ください。

例) 購入イベントをトリガーにして、作成されたキャンペーンをニュースフィードとして利用する場合

- ニュースフィードはキャンペーンとは別に独立して作成されるため、キャンペーンが表示されていなくてもニュースフィードとしては取得が可能になります。



### メッセージの表示タイミングを選択

メッセージの表示タイミングを制御することができます。 ユースケースによって以下の設定を行います。



#### 配信トリガーの発生後、すぐに表示

デフォルト設定項目として本項目が選択されます。
配信トリガーで設定したトリガー条件を満たした時点でメッセージを表示します。

##### NOTE
- 配信トリガーの設定については[こちら](#web-message-display-trigger) をご参照ください。

#### 配信トリガーの発生後、以下のいずれかの条件を満たした時表示

##### WARNING
- `配信トリガーの発生後、以下のいずれかの条件を満たした時表示` 機能を利用するには事前にカスタムJavaScriptを有効にしておく必要があります。カスタムJavaScriptの有効化に関しては [カスタムJavaScript](https://docs.repro.io/ja/dashboard/campaign/custom-js.md) をご参考ください。

**ページの %までスクロールした時**

配信トリガーで設定した配信トリガーの発生後、さらに指定した割合までページスクロールを行った時点でメッセージを表示します。

**秒後**

配信トリガーで設定した配信トリガーの発生後、さらに指定した秒数が経過した後にメッセージを表示します。

##### NOTE
- スクロール率は1%から100%まで指定できます。
- 秒数は1秒から18000秒（3時間）まで指定できます。
- **ページの %までスクロールした時** と **秒後** が同時に設定された場合は、一番最初に条件を満たしたものでメッセージが表示されます。

#### コントロールグループへのパターン設定の反映に関して

**配信トリガーの発生後、以下のいずれかの条件を満たした時表示** を利用する場合、効果測定をより正確に行うために下記の注意事項をご確認の上ご利用ください。

##### WARNING
- コントロールグループの振り分けが1%以上でパターン1のメッセージタイプが **スタンダード** の場合、パターン１で設定したスクロール率と経過時間がコントロールグループに自動反映されます
- コントロールグループの振り分けが1%以上でパターン1のメッセージタイプが **カスタム** の場合、 **スタンダード** から **カスタム** に変更した時点のスクロール率と経過時間を含むJavaScriptコードがコントロールグループに自動反映されます。ただし、それ以降に **カスタム** で行われた変更内容は自動的に反映されませんので、必要に応じてコントロールグループ内のJavaScriptを個別で編集してください
- コントロールグループの振り分けが1%以上でパターン1のメッセージタイプが **カスタム** の場合、`コントロールグループと比較をする際の条件や基準` を揃えるために、コントロールグループにもパターン1と同様なJavaScriptを設定頂くことを推奨しております



### 表示位置

Webメッセージの表示位置を設定します。表示タイプは **ウィンドウまたはページ上に固定** 、 **要素を指定して固定** 、 **埋め込み** の3種類があり、選択したテンプレートによって利用できる種類が異なります。



#### ウィンドウまたはページ上に固定

ウィンドウやページに対してコンテンツをポップアップ表示できます。



下記のフォームを入力します。



**位置**
: ページ全体に対して配置する位置を以下から指定します。
   
  - 左上
  - 上
  - 右上
  - 左
  - 中央
  - 右
  - 左下
  - 下
  - 右下



#### 要素を指定して固定

ページ内の特定の要素に対してコンテンツをポップアップ表示（浮かべて表示）します。



下記のフォームを入力します。



**基準の要素**
: 表示位置の基準となる要素をCSSセレクターで指定します。表示トリガー実行時に指定した基準の要素が存在しない場合はメッセージが表示されません。

**位置**
: 基準の要素に対して、配置する方向を以下から指定します。
   
  - 左上
  - 上
  - 右上
  - 左
  - 右
  - 左下
  - 下
  - 右下
   
  表示位置の基準は次の図のようになります。
   
  - 灰色の四角： 基準の要素
  - 赤色の四角： メッセージ
   
  
   
  例： **位置** を「右上」に設定した場合
   
  - 横軸： 基準の要素の横幅の中心がメッセージの左端に来るよう配置する
  - 縦軸： 基準の要素の上端がメッセージの下端に来るよう配置する

**オフセット**
: 指定された要素からの上下左右の距離をピクセル単位で調整することができます。数値はマイナスや小数でも指定可能です。

##### WARNING
- **基準の要素** や **位置** 、 **オフセット** を元に配置された表示位置がページの幅や高さから溢れる場合は、メッセージが途切れて全体が表示できなくなりますのでご注意ください。
- 管理画面上のプレビューには表示位置に関する設定が反映されません。実際の表示位置の確認は [プレビュー機能を使った確認方法](#web-message-preview) をご活用ください。



#### 埋め込み

下記の画像のようにページ内の特定の要素の前後または内部にコンテンツを埋め込みます。



下記のフォームを入力します。



**基準の要素**
: 表示位置の基準となる要素をCSSセレクターで指定します。表示トリガー実行時に指定した基準の要素が存在しない場合はメッセージが表示されません。

**位置**
: 基準の要素に対して、配置する位置を以下から指定します。
   
  - 前に挿入
  - 子要素の先頭に挿入
  - 子要素の末尾に挿入
  - 後ろに挿入

##### 基準となるCSSセレクターの取得方法

以下ではブラウザとして **Google Chrome** を利用する場合を想定しています。

**1. Chrome DevToolsを開く**

Ctrl+Shift+I キー（Windows）または Cmd+Opt+I キー（Mac）を埋め込みを行いたいWebページ上で押下します。すると下記のような画面が表示されます。



**2. 対象の要素のCSSセレクタを見つける**

上記の画像では右半分に表示されているElementsパネル（詳細は [こちら](https://developers.google.com/web/tools/chrome-devtools/inspect-styles) をご参照ください）上で基準となる要素を探します。Elementsパネル上のどの要素がWebサイト上のどの要素に対応するかが分かるので、下図では赤枠に表示されているCSSセレクタ（li.toctree-l2）をキャンペーン作成画面の基準の要素の項目に入力してください。



##### WARNING
- 管理画面上のプレビューには表示位置に関する設定が反映されません。実際の表示位置の確認は [プレビュー機能を使った確認方法](#web-message-preview) をご活用ください。
- 公開前に必ず意図したCSSセレクターが選択されているかを [プレビュー機能を使った確認方法](#web-message-preview) を用いてご確認ください。

##### コントロールグループへのパターンの設定の反映に関して

表示位置の指定が「要素を指定して固定」ならびに「埋め込み」のテンプレートを選択し、かつコントロールグループを利用したキャンペーンを配信する場合、効果測定をより正確に行うために下記のようなパターンの設定の引き継ぎが行われますのでご注意ください。

- **パターン1** の内容 がコントロールグループにも反映されます。

例) パターン1に下記のような設定を行った場合、コントロールグループにも同様の設定が反映されます





### コンテンツを作成する

テンプレート選択画面で選んだテンプレートを編集し、コンテンツを作成します。

選択したテンプレートによって設定可能なコンテンツは異なります。以下にタイプ別の代表的なコンテンツについて説明します。

##### NOTE
「変数の挿入」ボタンがある項目には、Liquid記法によってユーザープロフィールの値を挿入することができます。詳細は [Liquidによるパーソナライズ](https://docs.repro.io/ja/dashboard/campaign/liquid-personalization.md) をご覧ください。



#### ダイアログ

ダイアログタイプのWebメッセージでは、表示位置やオーバーレイの有無を指定して、画像やテキスト、ボタンを組み合わせたメッセージを表示することができます。例えば、ECにおけるクーポンや全員に周知したいアンケート・お知らせなど、ユーザーに強く主張したいコンテンツを表示するのに有効です。

どの要素を使えるかは選択したテンプレートによりますが、例えばボタンなら1つ ~ 4つの中で選択でき、指定のページを開くURLもしくはディープリンクを設定することもできます。

下記のフォームに入力してWebメッセージを作成します。



##### ダイアログ

**背景色**

ダイアログ部分の背景色の色を指定出来ます。

**横幅**

ダイアログの横幅を指定できます。pxによる絶対値もしくは%による相対値で指定が出来ます。

##### NOTE
- pxを指定した場合の最大値は640px, %を指定した場合の最大値は100%です。

**余白**

コンテンツ部分と外枠との間の余白を上下左右指定出来ます。

**枠線**

外枠の太さ及び色を指定出来ます。

**角丸**

外枠の角にどの程度丸みをつけるかを指定出来ます。

##### オーバーレイ

メッセージを表示する際に、画面全体を要素（オーバーレイ）で覆うかどうかを選択出来ます。オーバーレイをつけることでユーザーの動きを止めてメッセージに注目してもらうことができます。また、オーバーレイで覆われた画面をクリックすると、メッセージとオーバーレイのどちらも非表示となります。なお、チェックを外すことでオーバーレイを無効にすることも可能です。

**背景色**

ダイアログの背景の色を指定出来ます。

##### 閉じるボタン

メッセージを閉じるボタン（メッセージの右上に配置）の表示有無を選択出来ます。閉じるボタンを表示しない場合でも、オーバーレイを設定していればユーザーはメッセージを非表示にすることが出来ます。

**位置**

閉じるボタンの位置をダイアログの内側にするか、外側にするかを指定出来ます。

**背景色**

閉じるボタンの色を指定出来ます。

**アイコン**

閉じるボタンのアイコンの色を指定出来ます。

##### NOTE
- オーバーレイと閉じるボタンの両方を無くしてしまうと、ユーザーがメッセージを閉じれなくなります。

##### 見出し

メッセージのヘッダーを指定します。テキストの大きさ/太さ/左寄せ/中央寄せ/右寄せ/色/余白を指定出来ます。

##### 本文

メッセージの本文を指定します。テキストの大きさ/太さ/左寄せ/中央寄せ/右寄せ/色/余白を指定出来ます。

##### NOTE
- 本文・見出しの最大文字数は5000字です

##### 画像（画像を利用するテンプレートを選択時にのみ表示されます）

メッセージに表示する画像を指定します。ダイアログの画像サイズはテンプレートによって3種類のタイプがあります。

- ファイルフォーマット: JPEG、PNG
- ファイルサイズ
  - 最大: 1MB

**大きな画像のダイアログ**

- 画像サイズ
  - 推奨: 600px × 500px 以上（デスクトップ、モバイル）



**小さな画像のダイアログ**

- 画像サイズ
  - 推奨: 150px × 150px 以上（デスクトップ、モバイル）



**画像のみのダイアログ**

- 画像サイズ
  - 推奨: 800px × 800px（デスクトップ、モバイル）



#### 画像のカスタマイズ項目

画像は下記の項目が設定可能です。



**角丸**

画像の角をどの程度丸ませるかを指定することが出来ます。

**URLもしくはディープリンク (一部のテンプレートでのみ利用可能 / 任意)**

画像を押した時に指定したURLのページを開いたり、アプリを起動して、アプリ内の任意の画面に遷移することが出来ます。

**トラッキングイベント名 (任意)**

効果測定で利用可能な、画像を押した際に記録されるイベント名を指定することが可能です。

**横幅**

画像の横幅を指定することが出来ます。pxによる絶対値もしくは%による横幅に対する相対値で指定が出来ます。

##### ボタンの表示(ボタンを2個以上利用するテンプレートを選択時にのみ表示されます)

**余白**

ボタンの余白を指定することが出来ます。

**ボタンの配置**

ボタンの縦・横並びを選択可能です。

##### ボタン1 / ボタン2 / ボタン3 / ボタン4(ボタンを利用したテンプレートを選択時にのみ表示されます。)

ボタンに表示するテキストを指定します。テキストの大きさ/太さ/左寄せ/中央寄せ/右寄せ/テキストの色/ボタンの背景色/余白/ボタンの枠線の有無/外枠の角の丸みを指定出来ます。

##### NOTE
- ボタンのテキスト最大文字数は5000字です

##### URLもしくはディープリンク (任意)

URLもしくはディープリンクを指定すると、ボタンを押した時に指定したURLのページを開いたり、アプリを起動して、アプリ内の任意の画面に遷移することが出来ます。URLもしくはディープリンクを指定しないでボタンを押した場合は、Webメッセージが閉じられます。

##### NOTE
- URLもしくはディープリンクを指定しない場合、同一URLへの遷移として取り扱われてしまうことにより、画面のリロードが行われる場合があります。

- 文字列長
  - 最大: 1000文字

##### トラッキングイベント名 (任意)

トラッキングイベント名を指定すると、アクションボタンをクリックしたときに計測されるイベントを変更することが出来ます。

##### 代表的なダイアログ

ダイアログのテンプレートのうち、代表的なものを以下に取り上げます。

##### テキスト+ボタン



##### テキスト+画像



##### テキスト + 画像 + ボタン２つ



##### テキスト + 画像 + テキスト + ボタン２つ





#### 吹き出し

吹き出しタイプのWebメッセージでは、サイト上のメニューやボタンなど特定の要素にマッチするセレクタを指定して、そこにメッセージを表示します。例えば、購入ボタンや申し込みボタンといったCV要素のセレクタに直接ポップアップを表示させてCVを促進するのに有効です。

下記のフォームに入力してWebメッセージを作成します。



##### 吹き出し

**背景色**

吹き出し部分の背景色の色を指定出来ます。

**余白**

コンテンツ部分と外枠との間の余白を上下左右指定出来ます。

**枠線**

外枠の太さ及び色を指定出来ます。

**角丸**

外枠の角にどの程度丸みをつけるかを指定出来ます。

**矢印長さ**

吹き出しの矢印の長さを指定出来ます。

**矢印位置**

吹き出し矢印をメッセージの左からどの位置に出すかを指定出来ます。

##### 閉じるボタン

メッセージを閉じるボタンの表示有無を選択できます。閉じるボタンはメッセージの右上に配置されます。

**位置**

閉じるボタンの位置を吹き出しの内側にするか、外側にするかを指定出来ます。

**背景色**

閉じるボタンの色を指定出来ます。

**アイコン**

閉じるボタンのアイコンの色を指定出来ます。

##### NOTE
- 閉じるボタンを無くしてしまうと、ユーザーがメッセージを閉じれなくなります。

##### 見出し

メッセージのヘッダーを指定します。テキストの大きさ/太さ/左寄せ/中央寄せ/右寄せ/色/余白を指定出来ます。

##### 本文

メッセージの本文を指定します。テキストの大きさ/太さ/左寄せ/中央寄せ/右寄せ/色/余白を指定出来ます。

##### NOTE
- 本文・見出しの最大文字数は5000字です



#### 埋め込み

埋め込みタイプのWebメッセージでは、サイト上の特定の要素にマッチするセレクタを指定して、そこにメッセージを表示します。例えば、ヘッダーに最新のお知らせを表示したり、タイムセールを開催しているという情報を表示するのに有効です。

##### NOTE
1. 埋め込みテンプレートは画像・ボタンを押しても閉じません。
2. メッセージが閉じないので、効果測定においてボタンの押下数が多くなる可能性がございます。

下記のフォームに入力してWebメッセージを作成します。



##### 埋め込み

**背景色**

埋め込み部分の背景色の色を指定出来ます。

**横幅**

埋め込みの横幅を指定できます。pxによる絶対値もしくは%による基準となる要素に対する相対値で指定が出来ます。

##### NOTE
- pxを指定した場合の最大値は1440px, %を指定した場合の最大値は100%です。

**余白**

コンテンツ部分と外枠との間の余白を上下左右指定出来ます。

**枠線**

外枠の太さ及び色を指定出来ます。

**角丸**

外枠の角にどの程度丸みをつけるかを指定出来ます。

##### 見出し

メッセージのヘッダーを指定します。テキストの大きさ/太さ/左寄せ/中央寄せ/右寄せ/色/余白を指定出来ます。

##### 本文

メッセージの本文を指定します。テキストの大きさ/太さ/左寄せ/中央寄せ/右寄せ/色/余白を指定出来ます。

##### NOTE
- 本文・見出しの最大文字数は5000字です



#### カウントダウン

カウントダウンタイプのWebメッセージでは、指定された時刻までの残り時間を表示することが可能です。例えば、ECサイトであれば「期間限定セール終了まであと3日」のような表示を行うことで、CVの促進が期待出来ます。

カウントダウンのテンプレートはその他のテンプレートと組み合わせて、基本的な見た目を決定します。組み合わせ可能なテンプレートは以下です。詳細は各々のテンプレートをご参照ください。

[ダイアログ](#web-message-version-dialog)

[埋め込み](#web-message-version-embedded)

[吹き出し](#web-message-version-balloon)

##### カウントダウン設定

カウントダウンで表示するタイマーの設定を行います。



**終了日時**

タイマーの終了時刻を指定出来ます。

**タイマー表記**

タイマーの日時表記を指定出来ます。指定可能な形式は以下です

- 日
  - 例: 「3日」
- 日、時
  - 例: 「3日 3時間」
- 日、時、分
  - 例: 「3日 3時間 59分」
- 日、時、分、秒
  - 例: 「3日 3時間 59分 59秒」

**タイマー**

タイマーの日時の文字の大きさ/太さ/色を指定することが出来ます。

##### NOTE
カウントダウンの終了時刻を過ぎてもキャンペーンが終了していなかった場合、下図のように日時表記に応じて0が表示されます。例えば、下図では日時表記に「日、時、分、秒」を指定していたため、「0日 0時間 0分 0秒」のように表示されています。

##### NOTE
実際に表示されるタイマーの表記の単位は **当該のWebサイトのHTML要素のlang属性** によって決定されます。

例えば、タイマーの表記に日、時、分、秒を利用し、当該のWebサイトのHTML要素のlang属性が"en"だった場合、**1days 3hors 4minutes 3seconds** のように表示されます。

HTML要素のlang属性に関しては [公式サイト](https://developer.mozilla.org/ja/docs/Web/API/HTMLElement/lang) をご確認ください。



**タイマーの前に来るテキスト**

タイマーの日時の前に来るテキストを指定することが出来ます。上図を例に取ると「セール終了まで」の部分に相当します。

テキストの大きさ/太さ/色が指定出来ます。

**タイマーの後に来るテキスト**

タイマーの日時の後に来るテキストを指定することが出来ます。上図を例に取ると「急げ」の部分に相当します。

テキストの大きさ/太さ/色が指定出来ます。

**カウントダウン全体のデザイン調節**

カウントダウン全体の左寄せ・中央寄せ・右寄せ/余白が指定出来ます。

##### NOTE
カウントダウンのテンプレート内でカスタムメッセージを利用される場合は、誤って data-repro-template--countdown-wrapper 属性を消去しないようにご注意ください。効果測定が正しく行われません。



#### 固定バー

固定バータイプのWebメッセージでは、Webサイトの上部もしくは下部の決まった位置に常に配置され、ユーザーのページスクロールにも追従するメッセージを表示することが可能です。

例えばクッキー許諾などエンドユーザーに対して重要なインフォメーションやアクションを促したいといったユースケースで活用することが考えられます。

##### 固定バー

固定バーのテンプレートの位置や背景色の設定を行います。



**背景色**

固定バーの背景色の色を指定出来ます。

**余白**

コンテンツ部分と外枠との間の余白を上下左右指定出来ます。

**位置調整**

上下方向への固定バーの位置調整が可能です。

**上下位置**

画面上下のどちらに固定バーを表示するかを指定出来ます。



#### アイコン

アイコンタイプのWebメッセージでは、例えばTwitterのライクボタンのようなアイコンをWebサイトの右下などに常に表示し、ユーザーにアクションを促すといったことが可能です。

##### 表示位置



**位置**

アイコンをWebサイト上のどこに表示するかを左上/上など9通りから選びます。



##### 画像1

アイコンとして使う画像に関する設定を行います。

**角丸**

画像の角をどの程度丸めるかを指定出来ます。

**URLもしくはディープリンク (任意)**

アイコンを押した際の遷移先を指定出来ます。

**トラッキングイベント名（任意）**

アイコンを押した際にトラッキングされるイベント名を指定出来ます。

##### アイコン

**背景色**

アイコン部分の背景色の色を指定出来ます。

**横幅**

アイコンの横幅を指定できます。pxによる絶対値もしくは%による基準となる要素に対する相対値で指定が出来ます。

**位置調整**

水平方向/垂直方向の位置の調整が可能です。

##### 閉じるボタン

**閉じるボタン**

メッセージを閉じるボタンの表示有無を選択できます。閉じるボタンはメッセージの右上に配置されます。

**位置**

閉じるボタンの位置をアイコンの内側にするか、外側にするかを指定出来ます。

**背景色**

閉じるボタンの色を指定出来ます。

**アイコン**

閉じるボタンのアイコンの色を指定出来ます。

### キャンペーンをニュースフィードとして利用する

[キャンペーン設定](#web-message-campaign-settings) にて、キャンペーンをニュースフィードとして使うにチェックを入れた場合は、下記の画像のようなニュースフィード用の入力フォームがコンテンツ作成用のフォームの下に出現し、設定が可能です。詳細は [ニュースフィード](https://docs.repro.io/ja/dashboard/campaign/newsfeed.md) をご覧ください。



**タイトル**
: ニュースフィードのタイトルを指定します。ここで入力した値は、ニュースフィード内の `title` として取得が可能です。

**概要**
: ニュースフィードの概要を指定します。ここで入力した値は、ニュースフィード内の `summary` として取得が可能です。

**詳細（任意）**
: ニュースフィードの本文を指定します。ここで入力した値は、ニュースフィード内の `body` として取得が可能です。

**リンク先URL（任意）**
　ニュースフィードのリンク先となるURLを指定します。ここで入力した値は、ニュースフィード内の `link_url_string` （SDK） `link_url` （ニュースフィードAPI）として取得が可能です。

**画像（任意）**
　ニュースフィードに紐づく画像を指定します。ここでアップロードした画像のURLまたは入力したURLの値は、ニュースフィード内の `image_url_string` （SDK） `link_url` （ニュースフィードAPI）として取得が可能です。



#### プレビュー機能を使った確認方法

Webメッセージ・プレビュー機能を利用して、配信前のWebメッセージを指定したサイトで確認することができます。



**初めてプレビュー機能を使う場合**

1. メッセージ作成画面で「プレビューをサイトで確認」ボタンを押します。


1. メッセージを表示したいサイトのURLを入力し、「保存」ボタンを押します。
2. 「サイトで確認」ボタンを押す、生成されたURLをコピーして貼り付ける、QRコードをスキャンする、のいずれかで指定したサイトを開きます。
3. 開いた先のURLで作成・編集中のメッセージがプレビューとして表示されます。

**2回目以降の場合**

1. メッセージ作成画面で「プレビューをサイトで確認」ボタンを押します。
2. URLの入力欄に前回保存されたURLが表示されます。URLを変更したい場合は、変更後のURLを入力して「更新」ボタンを押します。
3. 「サイトで確認」ボタンを押す、生成されたURLをコピーして貼り付ける、QRコードをスキャンする、のいずれかで指定したサイトを開きます。
4. 開いた先のURLで作成・編集中のメッセージがプレビューとして表示されます。

##### NOTE
- 1度生成したプレビュー用のURLに変更後のメッセージ内容を再反映させたい場合は、「更新する」ボタンを押してください。
- プレビューが表示されたサイト上では、イベントのトラッキングはされず、プレビューしている以外のメッセージも表示されません。またプレビューを閲覧中はブラウザのコンソールにメッセージが出力されることがありますが、サイトの動作には影響を与えないためご安心ください。
- 管理画面上で生成されたプレビュー用のURLに有効期限はありません。
- メッセージに設定された配信条件（表示トリガーや配信対象設定など）はプレビューには反映されず、プレビュー用のURLを開くと必ずメッセージは表示されます
- 指定したサイトにバージョン2以上のWeb SDKが導入されていないとプレビューは表示されません。
- サイトによってはリダイレクトによりクエリパラメータが削除されたり、利用しているJavaScriptライブラリが遷移後にクエリパラメータを削除することがあります。こういったケースではメッセージのプレビューは表示されないのでご注意ください。



### カスタムメッセージ

[カスタムメッセージ](https://docs.repro.io/ja/dashboard/campaign/custom-message.md) の項目をご確認ください。

### 配信対象者を各パターンに振り分ける



[配信対象設定](#web-message-select-target) で設定した配信対象者をコントロールグループと、パターン1に振り分けます。
コントロールグループ(統制群)とは、 **Webメッセージを表示しない対象者** を指します。
キャンペーン自体の効果を計測するために、 **Webメッセージを表示するユーザー** と **Webメッセージを表示しないユーザー** で効果を比較できます。
パターンを増やした状態での設定方法は、 [A/Bテスト](#web-message-ab) をご覧ください。

例えば、配信条件を **既存ユーザー** とした場合に、コントロールグループを **20%** 、 パターン1を **80%** に設定すると、既存ユーザーの中からランダムで抽出された **約80%** のユーザーにメッセージが表示され、残りの **約20%** のユーザーにはメッセージは表示されません。

#### 割合を設定する

デフォルトではコントロールグループ **0%**、パターン1 **100%** となっているため、配信条件で指定したユーザーに **100%** 表示されます。
コントロールグループを利用しない場合は、設定を変更する必要はありません。
コントロールグループを利用する場合は、コントロールグループとパターン1で合計100%となるように割合を設定出来ます。

**均等に振り分ける** をクリックすると、コントロールグループとパターン1を **50%** ずつに均等に振り分けます。
**均等に振り分ける(コントロールグループなし)** をクリックすると、コントロールグループを **0%**、パターン1を **100%** に設定します。

##### NOTE
- コントロールグループは **0%** ~ **99%** まで設定出来ます。
- パターン1は **1%** ~ **100%** まで設定出来ます。
- 整数のみ設定出来ます。
- 振り分け設定は新規作成時のみ行うことが出来ます。
- 配信数の規模により、設定した割合と実際の配信数が乖離することがあります。



### 配信設定

**配信期間**
: キャンペーンを配信する期間を設定してください。ここで設定した期間、メッセージがユーザーごとに一度だけ表示されます。ユーザーは [ユーザーID](https://docs.repro.io/ja/dev/sdk/user-id.md) で区別されます。

**配信曜日**
: 配信曜日の指定が行えます。曜日を選択することで、該当曜日にメッセージが配信できます。指定しない場合は全ての曜日で配信が行われます。

**配信時間帯**
: 配信時間帯の指定が行えます。時間帯を選択することで、該当時間帯にメッセージが配信できます。指定しない場合は全ての時間帯で配信が行われます。

**表示頻度**
: このキャンペーンが各ユーザーに表示される回数を制御できます。複数回表示する場合は、累計回数（最大で2〜10回または無制限）を制限し、さらに1日の最大表示回数（1〜10回)も制限することができます。

##### NOTE
- 配信対象が初回ユーザーの場合、表示頻度は1回または無制限のみ設定できます。
- 1日の最大表示回数を指定しない場合、弊社システムの状況によっては、設定した回数以上メッセージが表示されることがございます。

##### WARNING
- 1ユーザーに複数回表示する場合、メッセージが表示されてから、Repro内部でメッセージが表示されたことを検知するまではメッセージが表示されません。

**メッセージの同時表示**
: 他のメッセージと同一PV上へ表示する有効/無効の指定が行えます。「他のメッセージとの同時表示を有効にする」にチェックをいれることで、同時表示が有効になります。指定しない場合は無効になります。

##### NOTE
- 同時表示が無効同士のメッセージの場合は、同一PV上にはどちらか一方のみが表示されます。
- 同一PV上への表示について、同時表示が無効のものは最大で1個、それに加え同時表示が有効のものがすべて表示されます。

例:

| メッセージA | メッセージB | 結果 |
| --- | --- | --- |
| 無効 | 無効 | AとBはどちらか一方しか表示されません |
| 有効 | 有効 | AとBのメッセージは両方表示されます |
| 無効 | 有効 | AとBのメッセージは両方表示されます |

**表示優先度**
: 同時表示が無効のメッセージの場合、優先度は **1** から **100** までの数値で指定でき、数値が大きいほど優先して表示されます。既定値は **50** です。

##### NOTE
同時表示を無効に指定しているメッセージが複数個同時に以下条件を満たしたとき、どちらが先に表示されるかは以下のルールで決定されます。
: - 優先度が高いメッセージが優先されて表示されます。
  - 同じ優先度のメッセージ同士の場合、更新日時が最新のものが優先されて表示されます。

例:

メッセージ表示トリガーが同じ以下の表示条件とした場合、
: - メッセージA　同時表示が無効　優先度80　1ユーザーに1回のみ表示
  - メッセージB　同時表示が無効　優先度50　1ユーザーに1回のみ表示

以下のように配信されます。
: - 1回目のアクセス　メッセージA　のみ表示されます
  - 2回目のアクセス　メッセージB　のみ表示されます



##### NOTE
本機能のリリース以前に「高中低」で設定されていた優先度は、以下のように変更されています。
: - 低: 30
  - 中: 50
  - 高: 80



### メッセージ表示トリガー

メッセージ表示トリガーによってメッセージの表示タイミングを制御することができます。
ユースケースによって以下の設定を行います。

##### NOTE
既存のイベントを利用せずに新しい条件でトリガーさせたい場合は、イベント選択時 **イベントを新規作成** を押下して新しいイベントを作成することが可能です。入力項目の詳細については [こちら](https://docs.repro.io/ja/dashboard/setting/web-tracking-rule.md) をご覧下さい。



#### イベント実行時にトリガーを実行する

指定したイベントが実行された場合にトリガーします。



**トリガーの種類**
: **イベントの実行** を選択します

**トリガー**
: 1. 最初の選択リストからイベントを指定します
  2. 次の選択リストから **実行時** を指定します

#### イベントの合計実行回数によってトリガーを実行する

指定したイベントが特定の回数だけ実行された場合にトリガーします。



**トリガーの種類**
: **イベントの実行** を選択します

**トリガー**
: 1. 最初の選択リストからイベントを指定します
  2. 次の選択リストから **合計実行回数** を指定します

**条件**
: - 合計実行回数
    - 数値は、最小2から最大30まで指定できます
    - 比較方法は「回目」、「回目以上」、「回目以下」が指定できます
  - 集計対象期間
    - 「セッション内」、もしくは「時間」、「分」、「秒」のいずれかから期間を指定できます

##### NOTE
- 期間を指定した場合は、最大3時間まで指定できます
- 期間は設定したイベントが新しく実行された時点から遡ります(例: 3/15 15:00 時点でイベントを実行した場合、集計対象期間が「3時間」であれば 3/15 12:00 以降が集計対象となります)

#### イベント実行時のイベントプロパティの値によってトリガーを実行する

指定したイベントプロパティが特定の値であった場合にトリガーします。



**トリガーの種類**
: **イベントの実行** を選択します

**トリガー**
: 1. 最初の選択リストからイベントを指定します
  2. 次の選択リストからイベントプロパティのキーを指定します
  3. 次の選択リストから **値** を指定します

**条件**
: - イベントプロパティの条件となる値を指定します
  - 比較方法は「と一致する」、「と一致しない」、「のいずれか」、「以上（数値）」、「以下（数値）」、「を含む（文字列）」、「を含まない（文字列）」、「正規表現に一致」、「正規表現に一致（大文字と小文字の違いを無視）」、「正規表現に一致しない」、「正規表現に一致しない（大文字と小文字の違いを無視）」から選択可能です

##### NOTE
- `正規表現に一致する` など、正規表現にもとづく条件を利用した場合、指定された値は `new RegExp()` の引数となり条件比較が行われます。正規表現の詳細な仕様については [MDNのドキュメント](https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Regular_Expressions) を参照してください。
- JavaScriptのオブジェクトに対してどのような比較が行われるかに関しては [イベントトリガー、Webメッセージの表示条件における値の扱いについて](https://docs.repro.io/ja/faq/web/object-compare.md) をご確認ください。



#### ユーザープロフィールのセットによってトリガーを実行する

ユーザープロフィールがセットされた際に、セットされる値が特定の値であった場合にトリガーします。



**トリガーの種類**
: **ユーザープロフィールのセット** を選択します

**トリガー**
: 1. ユーザープロフィールを指定します

**条件**
: - セットされる値
    - セットされる値を指定します
    - 一致する場合のみ有効です
    - セット前の値を指定することはできません
    - セット前と同じ値がセットされた場合でもトリガーが実行されます

##### WARNING
- Web SDKバージョン2.26.1以前では、 [ユーザープロフィールの条件付きセット操作](https://docs.repro.io/ja/dev/web/user-profile.md#web-user-profile-conditional-set) で一致する値がセットされた場合、または [ユーザープロフィールの増加値/減少値](https://docs.repro.io/ja/dev/web/user-profile.md#web-user-profile-increment-and-decrement) が  *セットされる値* と一致する場合でもトリガーが実行されます。ご注意ください。

##### NOTE
- Web SDKバージョン2.26.2以降は [ユーザープロフィールの条件付きセット操作](https://docs.repro.io/ja/dev/web/user-profile.md#web-user-profile-conditional-set) で一致する値がセットされた場合、または [ユーザープロフィールの増加値/減少値](https://docs.repro.io/ja/dev/web/user-profile.md#web-user-profile-increment-and-decrement) で計算結果が一致した場合でもトリガーは発火しません。



### 配信対象設定



イベントやユーザープロフィール、既存ユーザーといったセグメンテーションフィルターをつかって、配信対象となるユーザーを指定できます。
各フィルターは **and** 、 **and not** 、 **or** を使って、最大5個まで組み合わせられます。

- **and**: 指定した条件を全て満たすユーザーが対象になります
- **and not**: 指定した条件にあてはまるユーザーが対象から除外されます
- **or**: 指定した複数の条件のどれかにあてはまるユーザーが対象になります

例えば:

- 3日前にWebサイトを閲覧して、その後2日間Webサイトを閲覧してないユーザーへ配信する場合


- 性別が女性で直近3日以内にイベントAかイベントBのどちらかを実行したユーザーへ配信する場合



#### 対象デバイス

**全てのデバイス**、**スマートフォン/タブレット**、**PC** でアクセスしたユーザーを対象に配信することができます。

#### オーディエンスでフィルタリング

[オーディエンス](https://docs.repro.io/ja/dashboard/campaign/audience.md) で作成したセグメンテーションを利用することができます。

##### NOTE
- フィルターオーディエンス: 他のフィルタリング条件と組み合わせることはできません。
- インポートオーディエンス: 他のフィルタリング条件と組み合わせることができます。

#### イベントでフィルタリング

[イベント](https://docs.repro.io/ja/dev/sdk/tracking.md) を実行したユーザーをセグメンテーションすることができます。実行した期間や回数を指定することができます。

#### イベントプロパティでフィルタリング

[イベント](https://docs.repro.io/ja/dev/sdk/tracking.md) を実行したユーザーのうち、実行されたイベントに付帯するプロパティにもとづいてユーザーをセグメンテーションすることができます。プロパティの名前や値、実行した期間や回数を指定することができます。

#### ユーザープロフィールでフィルタリング

[ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md) に登録されている情報にもとづいてユーザーをセグメンテーションすることができます。SDKでプロフィールの型に数値を指定している場合、「以上、以下、より大きい、より小さい」などをつかって、値を比較する条件を指定できます。文字を指定している場合、「一致する、一致しない、含む」などをつかって、条件を指定できます。日付を指定している場合、「◯日前以前、◯日前〜▢日前、特定日以前」などをつかって、条件を指定できます。

日付の指定については、[サポートサイトのFAQ](https://support.repro.io/hc/ja/articles/23886462974489) に詳細な説明がありますので、こちらも参考にしてください。

#### 全ユーザー

Reproへの登録の有無に関わらず、全てのユーザーが対象になります。全ユーザーを利用する場合は、 **その他の条件をフィルターに使うことができません** ので、ご注意ください。



#### 初回ユーザー

初めてSDKが入ったページを開いたユーザーが対象になります。なお、初回ユーザーのセグメントは初回セッション内（=初めてSDKが入ったページを開き、最後に発火されたイベントから30分以内）でのみ有効となりますので、ご注意ください。

**初回ユーザでなくなる場合の具体例**

- 5 / 1 19:00 SDKが入ったページを初めて訪問し、最初のイベント(A)を実行
- 5 / 1 19:31 イベント(B)を実行

上記の場合、**イベント（B)をトリガーとして、初回ユーザーにWebメッセージを表示することはできません** のでご注意ください。

#### 既存ユーザー

Reproに登録されたすべてのユーザーが対象となります。既存ユーザーから特定条件を満たすユーザーを除外する場合は、 **and not** でフィルターを追加してください。



### 下書きとして保存

キャンペーンの必須項目をすべて記入していない状態など、キャンペーンの作成途中で作成を終えたい場合は、 **下書きで保存** をクリックしてください。
下書きで保存をした場合は、後からキャンペーンのゴールやメッセージのパターンを変更することができます。

下書き状態のキャンペーンはメッセージ一覧画面の下書きタブから選択できます。





### 公開、もしくは、非公開にする

公開もしくは非公開をクリックする前に、設定したキャンペーンの内容を注意深くチェックしてください。
キャンペーンを公開、非公開で登録後からキャンペーンのゴール、メッセージのパターン が **変更できなくなります。**

確認後、キャンペーンを公開する準備が整っていれば、 **公開** を、そうでない場合は **非公開** をクリックしてください。



### 効果測定

キャンペーンの効果を確認できます。



#### 配信結果

**配信数**
: Webメッセージが表示されたユーザー数を日次で集計し、合計した数です。

**コンバージョン数**
: 配信から24時間以内に、作成画面で指定したゴールを達成したユーザーの数を日次で集計し、合計した数です。

**コンバージョン率**
: コンバージョン数 / 配信数 です。

**結果の推移**
: キャンペーン実施期間中の配信数、コンバージョン数を日次で集計した結果を表示しています。計測単位はユーザーです。



### A/Bテスト

配信対象に指定したユーザーに複数のパターンのメッセージを均等に出し分けることで、どのようなメッセージを配信すればコンバージョン率が向上するのかを検証することができる機能です。

最も効果の高かったメッセージを勝ちパターンとして指定することができます。

#### メッセージ作成

メッセージのパターンを2個以上作成することで、A/Bテストを行うことができます。


- メッセージは最大4パターンまで追加することができます。
- パターンの追加や削除は新規作成時のみ行うことができます。

#### 配信対象者を各パターンに振り分ける



パターンを2つ以上に設定した場合も、各パターンに配信対象者を振り分けられます。
コントロールグループを含む各パターンの合計が100%になるように設定します。

**均等に振り分ける** をクリックすると、コントロールグループと各パターンを均等に振り分けます。
**均等に振り分ける(コントロールグループなし)** をクリックすると、コントロールグループを **0%** に設定し、 **100%** を各パターンで均等に振り分けます。

##### NOTE
- コントロールグループは **0%** ~ **99%** まで設定出来ます。
- 各パターンは **1%** ~ **100%** まで設定出来ます。
- 整数のみ設定出来ます。
- 振り分け設定は新規作成時のみ行うことが出来ます。
- 配信数の規模により、設定した割合と実際の配信数が乖離することがあります。



#### 効果測定（A/Bテスト）

**詳細画面**



配信数やコンバージョン数が計上されると効果測定結果が表示されます。グラフにはWEBメッセージの配信数、各ボタンの押下数、コンバージョン率がパターンごとに表示されています。キャンペーンのデータ更新タイミングについての詳細は [こちら](https://docs.repro.io/ja/dashboard/misc/aggregation.md) をご覧ください。

##### NOTE
- コントロールグループの各データはキャンペーン自体の効果を判断しやすくするため、キャンペーン全体の **配信数**、**コンバージョン数**、**コンバージョン率** には反映されません。
- コントロールグループに属するユーザーにはWebメッセージは配信されないため、配信数、ボタン1押下数、ボタン2押下数は常に **-** で表示されます。
- コントロールグループのコンバージョン数は、コントロールグループに属するユーザーがキャンペーンに設定したゴールのイベントを発生させた数を表示します。
- コントロールグループのコンバージョン率は、コンバージョン数をコントロールグループに属するユーザー数で割って算出されます。

利用されるテンプレートの種類・テンプレ内で利用している要素によって効果測定画面に表示される要素が異なります。詳細は下記をご参照ください。なお、表中の標準はWEBメッセージのテンプレート選択画面において、オリジナル以外のものに対応し、カスタムはカスタムメッセージを用いた場合を表します。

##### 効果測定表示項目

|  | 標準 | カスタムメッセージ |
| --- | --- | --- |
| 表示項目 | **テンプレート内で利用している要素に応じて変動。** (例えばボタンを2個、画像を2個利用するテンプレートでは、効果測定にはボタン1 / ボタン2 / 画像1 / 画像2が表示されます。) | **テンプレ内で利用している要素とは無関係にボタン1 / ボタン2 / ボタン3 / ボタン4 / 画像1 / 画像2 / 画像3 / 画像4** が表示 |

A/Bテストの実行中にはA/Bテストの実行結果が表示されます。ここではコントロールグループを含む各パターンを選択した指標 (ボタン1押下率、ボタン2押下率、メインコンバージョン率、サブコンバージョン率) を用いて比較を行えます。



**パターン**

コントロールグループを含む、A/Bテストで送信を行う各パターンが表示されます。

**ベースライン**

A/Bテストで各パターンを比較する際に基準となるパターンをベースラインとして選択します。ベースラインを変更することで、様々なパターン間の比較ができます。

**対象となる指標**

A/Bテストで各パターンをベースラインと比較する際に用いる指標を選択します。指標には割合を表す値 (ボタン1押下率、ボタン2押下率、メインコンバージョン率、サブコンバージョン率) が選択できます。また、一覧に表示する指標については編集画面から変更できます。

**90%信頼区間**

各パターンをベースラインと比較した場合の 90% 信頼区間が表示されます。90% 信頼区間そのものの意味については [FAQ](https://docs.repro.io/ja/faq/general/significant-difference/5.md) をご参照ください。ここでは代表的なパターンの読み取り方について示します。

パターン１：



このような表示の場合、パターンとベースラインとの差が有意であることを意味します。配信を開始してから十分な期間が経過している場合、勝ちパターンの決定へと進むことを推奨します。

パターン２：



このような表示の場合、パターンとベースラインとの差が有意ではないことを意味します。結果が出るまでもう少し待つか、配信を開始してから十分な期間が経過している場合、差がないものとして次のキャンペーンの開始を検討することを推奨します。

パターン３：



このような表示の場合、パターンとベースラインとの差が有意であることを意味します。このような表示しかない場合、ベースラインとして設定しているパターンを勝ちパターンして決定することを推奨します。

パターン４：



このような表示の場合、そのパターンは指標の値が存在しないため、有意差の計算が不可能であることを意味します。

##### NOTE
- A/Bテスト有意差 測定結果は勝ちパターンを選択すると下記のような表示になり、各パターンの比較結果が表示されないようになります



**結果の推移**

グラフにはWebメッセージの配信数、ボタン1押下数、ボタン2押下数、メインコンバージョン率、サブコンバージョン率がパターンごとに表示されています。



**一覧画面**

A/Bテストを実行しているキャンペーンが公開中または非公開の場合に、一覧画面で各キャンペーンのA/Bテストの状態を確認できます。
アイコンの表示条件は次のとおりです。

| アイコン | 表示条件 |
| --- | --- |
|  | 有意差があり、ベースラインを上回る結果のパターンが1つ以上存在する場合 |
|  | 有意差があり、ベースラインを下回る結果のパターンのみが存在する場合 |
|  | 有意差がないパターンのみが存在する場合 |
|  | 全てのパターンで計算ができない場合 |
|  | 勝ちパターンを選択済みの場合 |
|  | A/Bテストを実行していて、ベースラインとなるパターンか対象となる指標が設定されていない場合 |
| ー | キャンペーンがA/Bテストを実行していない場合 |

##### NOTE
- 有意差があり、ベースラインを上回る結果と下回る結果のキャンペーンが両方ともに存在する場合には、ベースラインを上回る結果が1つでも存在する場合として表示がされます
- ご不明点がある場合 [FAQ](https://docs.repro.io/ja/faq/general/index.md) もあわせてご確認ください

#### 勝ちパターンを選ぶ

勝ちパターンを選ぶと、以降はそのパターンのみが配信対象のユーザーに配信されるようになります。

---

## カスタムJavaScript

### カスタムJavaScriptとは？

[カスタムメッセージ](https://docs.repro.io/ja/dashboard/campaign/custom-message.md) の機能を利用することで、Webサイトのイメージに合わせたWebメッセージの作成が可能です。

カスタムJavaScriptの機能を使うことで、例えばWebメッセージをフェードインさせたり、スクロール量に応じて表示するといったカスタムメッセージのみでは難しいよりリッチな表現が可能になります。

##### WARNING
- 本機能を利用することで生じた一切の損失に関して、当社は責任を負いかねます。詳しくはRepro利用規約([https://repro.io/company/legal/term/](https://repro.io/company/legal/term/))をご確認ください。
- 機能の実装につきましては、 **必ずHTML/CSS/JavaScriptの知識** を持った方が行うようにしてください。

### 導入手順

#### 1.JavaScriptの編集機能を有効にする

管理画面の設定 > プロジェクト設定 > 機能設定からWebメッセージのJavaScript編集機能をONにしてください。



##### NOTE
- 管理画面の **「オーナー」権限をお持ちの方のみ** が行うことができます

#### 2.カスタムメッセージを作成する

[カスタムメッセージ](https://docs.repro.io/ja/dashboard/campaign/custom-message.md) を参考にしてメッセージを作成してください。

#### 3.カスタムメッセージに動きをつける

2.で作成したメッセージの編集画面のコンテンツでJavaScriptを選択してJavaScriptを編集をすることができます。



実装例に関しては、 [こちら](#custom-js-sample) をご参照ください。

##### NOTE
- メッセージを表示するためには、必ず **message.show();** を当該のスクリプト内で呼ぶ必要がございます。
- **data-repro--close** 属性のついた要素が存在しないメッセージの場合、必ず当該のスクリプト内ののどこかで **message.close()** を実行してください。 **message.close()** が実行されない場合、メッセージを閉じることができません。
- 当該のスクリプトは **ローカルな関数スコープとして実行されます** ので、ご注意ください。
- 当該のスクリプトに対する **トランスパイルの処理は行われません** ので、ご注意ください。
- JavaScriptとして記述する内容については一切の制限を行いませんが、jQueryなどのライブラリはロードしません。
- JavaScriptエディター内のLinterは、JSHintを使用しています。

#### 4.作成したカスタムメッセージを確認する

思った通りの動きを実現出来ているかをサイト内プレビューの機能を使って、確認することが出来ます。



##### NOTE
- サイト内プレビューとして表示されたメッセージはイベント/ユーザープロフィールや、効果測定に関わるデータは一切アップロードされません。

(例) 下記サンプルコード内の reproio("track", "【CV】click_view"); はサイト内プレビュー時は実行されず、「イベント設定」への反映も行われません。

```js-web
window.addEventListener('click', (event) => {
    message.close();
    reproio("track", "【CV】click_view");
},true)
```

- サイト内プレビューや公開時、カスタムJavaScriptで記述したJavaScriptでエラーが発生している場合は、ブラウザの検証ツールにエラーメッセージが表示されます。ご注意ください。



### 実装例

以下のスクリプトはあくまでサンプルになりますので、その旨ご了承の上ご利用ください。

#### 1.ページを50%スクロールしたら、メッセージを表示させる。

```js-web
var body = window.document.body;
var html = window.document.documentElement;
window.addEventListener('scroll', function onScroll() {
    var scrollTop = html.scrollTop || body.scrollTop;
    var pageHeight = Math.max.apply(null, [body.clientHeight, body.scrollHeight, html.scrollHeight, html.clientHeight]);
    var viewHeight = html.clientHeight || body.clientHeight;
    var scrollRate = ((scrollTop + viewHeight) / pageHeight) * 100;
    if (scrollRate > 50) {
        message.show();
        window.removeEventListener('scroll', onScroll);
    }
});
```

#### 2.メッセージの表示を5秒遅らせる

```js-web
window.setTimeout(function() {
    message.show();
}, 5000);
```

### セキュリティに関するTips

#### Session cookieに関して

お客様のReproアカウントが乗っ取られた場合に、本機能はXSSのSINKとなる可能性がございます。そのような攻撃に備えて、Webサイト内でご利用されている **session cookieにHttpOnly属性がついているか** のご確認をお願い致します。

### 効果測定に関する注意点

- コントロールグループを利用される場合、「コントロールグループと比較をする際の条件や基準」 を揃えるためにコントロールグループにも、その他のパターンと同様にJavaScriptを設定頂くことを推奨しております。

(例) ページを50%スクロールした際にメッセージを表示する施策について、その施策を行うこと自体の効果を測りたい

以下のように通常パターンでスクロール50%でメッセージを表示する場合、コントロールグループにもスクロール50%で計測するよう同様のJavaScriptを設定する


- コントロールグループが0%の場合は、コントロールグループのタブを選択しても下記のように表示され、コンテンツの編集が行えません。



##### NOTE
- カスタムJavaScriptが有効になっていない場合は、JavaScriptの編集自体が行えませんのでご注意ください。
- インプレッションに計上されるタイミングは、 message.show() が実行されたタイミングです。

(例) 下記サンプルコードの場合、メッセージの表示トリガーが発火してから5秒以内にユーザーがサイトを閉じた場合は「インプレッション」にカウントされません。

```js-web
setTimeout(function() {
    message.show();
}, 5000);
```

### その他の注意点

#### カスタムJavaScriptを有効から無効に切り替えた場合の挙動について

設定 > プロジェクト設定 > 機能設定から"WebメッセージのJavaScript編集機能"をONからOFFに変えた際は、**カスタムJavaScriptを使ったWebメッセージの配信自体がなくなるわけではなく、Webメッセージの配信自体は行われ、カスタムJavaScriptを使って記述された振る舞いのみが無効** になります。当該のWebメッセージを停止したい場合は、メッセージ画面から停止してください。

---

## カスタムメッセージ

##### WARNING
- カスタムメッセージの利用時は、必ずHTML/CSS/JavaScriptの知識・経験の豊富な人が操作・編集を行ってください。
- 動的なスクリプト実行を防ぐため、不正な要素や属性は実際のメッセージ上では消えていたり、サニタイズされて無効化される場合があります。利用可能なタグの一覧は [カスタムメッセージで利用可能なHTMLタグ・属性](https://docs.repro.io/ja/dashboard/campaign/available-tags.md) を参照してください。
- テンプレートの内容をそのまま利用しない限り、カスタムメッセージの編集画面上でレスポンシブ対応に必要なCSSやアニメーションのCSSの記述はございません。必要に応じて適宜ご準備ください。

### カスタムメッセージを作成する

カスタムメッセージを作成する方法は2種類あります。

#### スタンダードテンプレートを利用する

1. 配信したいメッセージをテンプレートの一覧から選択し、Webメッセージの作成画面でタイプにある **カスタム** を選択します。



1. カスタムボタンを押下すると、テキストエディタが画面左側に表示されます。選択したテンプレートのHTML、CSSがそのままセットされていますので、必要に応じてHTMLやCSSを編集してください。



##### NOTE
- スタンダードで入力されたテキストの内容は画像も含めカスタムへ引き継がれます。
- カスタムで編集した内容はスタンダードへ引き継がれません。また、カスタム編集中にスタンダードへ変更するとカスタムで編集した内容は破棄されます。

#### オリジナルテンプレートを利用する

テンプレートの一覧からオリジナルテンプレートを選択します。



### カスタムメッセージを編集する

#### カスタムメッセージの表示位置を設定する

オリジナルテンプレートの場合、表示タイプを選択してください。
詳細は [表示位置](https://docs.repro.io/ja/dashboard/campaign/web-message.md#web-message-position) をご覧ください。



#### パターンを複製する

1. メッセージ項目にある **追加** ボタンを押下し、 **パターンを複製** ボタンを押下します。



1. 複製されたパターンが表示されるので、エディタからメッセージを編集します。なお、カスタムメッセージでパターンを複製した場合は、スタンダードタイプのメッセージに変更することはできません。

#### カスタムメッセージを複製する

1. 複製したいカスタムメッセージを選択し、複製ボタンを押下します。なお、複製元がカスタムメッセージの場合はスタンダードタイプのメッセージに変更することはできません。



1. メッセージ編集画面に遷移後、エディタからメッセージを編集します。



### コンテンツを編集する

コンテンツを編集します。
HTMLは以下のルールに沿って編集してください。

- トップレベルが単一の要素となるよう記述してください。

```html
<!-- Good -->
<div>
  <div>message1</div>
  <div>message2</div>
</div>

<!-- Bad -->
<div> message1</div>
<div> message2</div>
```

- トップレベルがタグで囲まれた要素となるよう記述してください。

```html
<!-- Good -->
<p>message</p>

<!-- Bad -->
message
```

#### メッセージを非表示にする要素を設定する

1. メッセージの一番外側の要素に `data-repro--wrapper` 属性を設定してください。

```html
<div class="container" data-repro--wrapper> message </div>
```

1. 対象要素に `data-repro--close` 属性を追加してください。

```html
<div class="btn" data-repro--close> ☓ </div>
```

#### 効果測定で計測されるアクションボタンを設定する

アクションボタンに属性を設定することで、任意の要素へのクリックなどを効果測定の配信結果に表示される **ボタン1押下数** 、 **ボタン2押下数** として集計することが可能です。

1. メッセージの一番外側の要素に `data-repro--wrapper` 属性を設定してください。

```html
<div class="container" data-repro--wrapper> message </div>
```

1. ボタン1・2押下数として効果測定したい要素に対して、それぞれ `data-repro--primary-btn` と `data-repro--secondary-btn` の属性を付与します。

```html
<div class="btn" data-repro--primary-btn>button_1</div>
<div class="btn" data-repro--secondary-btn>button_2</div>
```

##### NOTE
カスタムメッセージ内でアクションボタンを利用される場合は誤って data-repro--primary-btn ないしは data-repro--secondary-btn 属性を消去しないようにご注意ください。効果測定が正しく行われません。

##### NOTE
data-repro--no-close 属性をアクションボタンに付与することで、ボタンを押下してもメッセージを閉じないように挙動を変更することが可能です。

##### NOTE
WebSDKの仕様上、target="_blank" をアクションボタンに設定していてもリンク先への遷移は下記のような振る舞いに上書きされますので、ご注意ください。

- 当該のWebサイトと同一ドメインのリンクを遷移先に設定した場合
  - 現在開かれているタブと同一のタブ上でリンク先へと遷移
- 当該のWebサイトと別ドメインのリンクを遷移先に設定した場合
  - 現在開かれているタブとは別のタブ上でリンク先へと遷移

#### アニメーションを設定する

カスタムメッセージの表示・非表示の動きはそれぞれWeb SDKにより対象の要素の **opacity** プロパティを **0** と **1** に変更することで実現しています。
例えば、フェードインなどをご利用の場合は、 **opacity** プロパティの振る舞いをもとに適切な要素に **opacity** プロパティを記述してください。

#### カスタムメッセージで画像を設定する

1. メッセージで画像を利用する場合は、HTML上で挿入したい位置にカーソルを合わせ、テキストエディタ下部にある **画像を追加** ボタンを押してください。



1. パソコン上のフォルダから画像を選択して画像をアップロードすると、指定したカーソルの位置に `img src=` のタグと画像のURLが生成され、プレビュー上にも画像が反映されます。



##### NOTE
- **画像を追加** ボタンでアップロードできる画像ファイルサイズは最大1MBです。なお、 **画像を追加** ボタンを用いなければ、利用できる画像サイズに制限はありませんが、推奨画像サイズは変わらず最大1MBです。
- 管理画面上のプレビューは作成画面上のものとなるため、実機でも見た目をご確認ください。
- 実機でのプレビューは、 [Webメッセージ](https://docs.repro.io/ja/dashboard/campaign/web-message.md) の **プレビュー機能を使った確認方法** をご確認の上、プレビュー機能をご活用ください。
- **script** タグは使用できません。



#### カスタムメッセージでCSSのスコープを設定する

カスタムメッセージ内で作成されたCSSはデフォルトでは、コンテンツ下部にあるチェックボックスにありますように、カスタムメッセージ内でのみ有効となります。



当該のCSSをグローバルスコープでご利用されたい場合は上記のチェックボックスのチェックをはずしてください。

### その他の設定

配信設定などのその他のメッセージ設定につきましては、 [Webメッセージ](https://docs.repro.io/ja/dashboard/campaign/web-message.md) をご確認ください。

---

## カスタムメッセージで利用可能なHTMLタグ・属性

カスタムメッセージでは以下のタグと属性が利用可能です。動的なスクリプト実行を防ぐため、以下のタグと属性以外はサニタイズされて無効化されます。

##### WARNING
- 無効化されるタグと属性一覧は機能改善やバグ修正によって事前の予告なく変更される可能性があります。

### 任意のタグの中で利用可能な属性

以下の属性は全ての利用可能なタグにおいて利用可能です。
: - id
  - class
  - style
  - data-repro--wrapper
  - data-repro--close
  - data-repro--primary-btn
  - data-repro--secondary-btn
  - data-silver-egg-cref
  - data-silver-egg-prod

### 利用可能なタグと属性の一覧表

以下のタグがカスタムメッセージ内で利用可能です。また、[任意のタグの中で利用可能な属性]() に加えて各タグで利用可能な属性が存在します。表中では [任意のタグの中で利用可能な属性]() を「\*」 で表しています。

| タグ | 利用可能属性 |
| --- | --- |
| a | target, href, title, \* |
| abbr | test, \* |
| address | \* |
| area | shape, coords, href, alt, \* |
| article | \* |
| aside | \* |
| audio | autoplay, controls, loop, preload, src, \* |
| b | \* |
| bdi | dir, \* |
| bdo | dir, \* |
| big | \* |
| blockquote | cite, \* |
| button | autofocus, disabled, form, formaction, formenctype, formmethod, formnovalidate, formtarget, name, type, value, \* |
| br | \* |
| caption | \* |
| center | \* |
| cite | \* |
| code | \* |
| col | align, valign, span, width, \* |
| colgroup | align, valign, span, width, \* |
| dd | \* |
| del | datetime, \* |
| details | open, \* |
| div | \* |
| dl | \* |
| dt | \* |
| em | \* |
| fieldset | disabled, form, name, \* |
| font | color, size, face, \* |
| footer | \* |
| form | accept, accept-charset, action, autocomplete, enctype, method, name, novalidate, target, \* |
| h1 | \* |
| h2 | \* |
| h3 | \* |
| h4 | \* |
| h5 | \* |
| h6 | \* |
| header | \* |
| hr | \* |
| i | \* |
| img | src, alt, title, width, height, \* |
| input | accept, align, alt, autocomplete, autofocus, checked, dirname, disabled, form, formaction, formenctype, formmethod, formnovalidate, formtarget, height, list, max, maxlength, min, multiple, name, pattern, placeholder, readonly, required, size, src, step, type, value, width, \* |
| ins | datetime, \* |
| label | for, form, \* |
| legend | \* |
| li | \* |
| mark | \* |
| nav | \* |
| ol | \* |
| option | disabled, label, selected, value, \* |
| optgroup | disabled, label, \* |
| p | \* |
| pre | \* |
| s | \* |
| section | \* |
| select | autofocus, disabled, form, multiple, name, required, size, \* |
| small | \* |
| span | \* |
| sub | \* |
| sup | \* |
| strong | \* |
| table | width, border, align, valign, \* |
| textarea | autofocus, cols, dirname, disabled, form, maxlength, name, placeholder, readonly, required, rows, wrap, \* |
| tbody | align, valign, \* |
| td | width, rowspan, colspan, align, valign, \* |
| tfoot | align, valign, \* |
| th | width, rowspan, colspan, align, valign, \* |
| thead | align, valign, \* |
| tr | rowspan, align, valign, \* |
| tt | \* |
| u | \* |
| ul | \* |
| video | autoplay, controls, loop, preload, src, height, width, \* |

---

## データの更新タイミング

新たに取得もしくは更新されたイベントやユーザープロフィールなどのデータは、データの種別毎に反映されるタイミングが異なります。
各データが集計され、日次のアナリティクス分析結果や、マーケティング機能の配信対象として反映されるまでの時間は下記の通りです。

##### NOTE
- 弊社システムの状況によっては、反映までの時間が前後する可能性があります。

### アプリ内メッセージ・WEBメッセージ・アプリ内パラメーター

| 対象データ | 反映までの時間 |
| --- | --- |
| イベント | 数分間 |
| イベントプロパティ | 数分間 |
| ユーザープロフィール | 数分間 |
| 初回ユーザー | 数分間 |
| 既存ユーザー | 数分間 |

##### WARNING
- キャンペーンの作成、もしくは既存キャンペーンの配信対象を更新した場合、作成・更新を行ってから1時間以内は一部の配信対象ユーザーにキャンペーンが配信されない可能性があります。

### プッシュ通知

| 対象データ | 反映までの時間 |
| --- | --- |
| イベント | 数分間 |
| イベントプロパティ | 数分間 |
| ユーザープロフィール | 数分間 |
| 既存ユーザー | 数分間 |

### アナリティクス

各アナリティクス画面における日次、週次、月次の分析データは、それぞれの単位期間によって管理画面へ反映されるタイミングが異なります。

1. **日次**: 翌日に反映
2. **週次**: 翌週月曜日に反映
3. **月次**: 翌月1日に反映

データの集計完了前の段階では、その時点で集計が完了している暫定値が出力されます。

### マーケティング

マーケティングの配信数・開封数などの配信結果は当日分と前日より過去分で更新頻度が異なります。

1. **速報値**: 当日の配信結果は5〜15分おきに更新されます。
2. **実測値**: 前日より過去分の配信結果は1日2回集計されます。

##### NOTE
- **速報値** は **実測値** と最大5%程度の差が生じる可能性があります。

---

## 信頼区間とはなんですか？

- 対象となる指標 (CVRや開封率、ボタン押下率など) について統計的な処理を行い、対象になる指標の差がとりうる可能性の高い値の幅を推定したものです。計算には [t分布](https://en.wikipedia.org/wiki/Student%27s_t-distribution) を用いています。詳細は例えば [Confidence interval](https://en.wikipedia.org/wiki/Confidence_interval) を参照ください。
- 数値はベースラインに対する比を表示しています。たとえば、ベースラインの CVR が 10.0％ のとき、パターン 1 の CVR がベースラインに対して +2.0% 〜 +3.0 % 程度向上すると推定した場合には、画面上では +20.0% 〜 +30.0% と表示されます。

---

## 共通

### アナリティクス

* [アナリティクスに反映されるのはいつですか？](https://docs.repro.io/ja/faq/general/analytics/1.md)

### A/Bテスト 有意差表示

* [算出に利用している数値はどの時点で集計されたものですか？](https://docs.repro.io/ja/faq/general/significant-difference/1.md)
* [「まだ有意差がありません」の表示から変わらないのですが、いつ頃終わるかの目安はありますか？](https://docs.repro.io/ja/faq/general/significant-difference/2.md)
* [どの程度の配信数から結果の表示ができますか？](https://docs.repro.io/ja/faq/general/significant-difference/3.md)
* [有意差とはなんですか？](https://docs.repro.io/ja/faq/general/significant-difference/4.md)
* [信頼区間とはなんですか？](https://docs.repro.io/ja/faq/general/significant-difference/5.md)
* [有意差ありとでたらそれ以降で判定結果は変わりませんか？](https://docs.repro.io/ja/faq/general/significant-difference/6.md)
* [過去の有意差は見られますか？](https://docs.repro.io/ja/faq/general/significant-difference/7.md)
* [信頼区間で用いている有意水準 (信頼水準) は変更できますか？](https://docs.repro.io/ja/faq/general/significant-difference/8.md)

### API

* [リクエスト実行状況を意識して、APIを利用する必要はありますか？](https://docs.repro.io/ja/faq/general/api/1.md)

### その他

* [アプリ利用ユーザーへデータ取得の許諾を取る必要はありますか？](https://docs.repro.io/ja/faq/general/misc/2.md)
* [Reproから来る通知メールをOFFにできますか？](https://docs.repro.io/ja/faq/general/misc/3.md)
* [配信対象設定で利用できるマーケティング機能関連のイベントは何がありますか？](https://docs.repro.io/ja/faq/general/misc/4.md)

---

## アナリティクスに反映されるのはいつですか？

アナリティクスは集計対象の期間によって反映までの時間が異なります。詳しくは [データの更新タイミング](https://docs.repro.io/ja/dashboard/misc/aggregation.md) をご覧ください。

---

## 算出に利用している数値はどの時点で集計されたものですか？

詳細画面で表示される数値と同一のタイミングで集計された数値を表示しています。

---

## 「まだ有意差がありません」の表示から変わらないのですが、いつ頃終わるかの目安はありますか？

- どの程度のデータを収集すれば良いかはケース・バイ・ケースであり、一概に決めることは困難です。以降では一般論を記述します。
- A/Bテストを実施する期間については、平日と週末とではユーザーの行動が異なることが考えられますので期間は2週間程度を推奨します。
- A/Bテストの結果を得るために最低限必要な送信数は、場合によりますが各パターンについて 100 - 1,000 程度になります。送信数がこれを大きく超えて結果が出ていない場合には、差がないとみるべきでしょう。

##### NOTE
統計的には次のパラメーターから必要な配信数の見積もりが可能です。

1. 有意水準
2. 検出力
3. 対象とする指標 (CVR, 開封率など) の見込みの値
4. どの程度の差を認めた場合に意味があるとみなすかの閾値

上記の100 - 1,000という数値は上記のパラメーターについて典型的なものを与えたときに計算される数値です。

---

## どの程度の配信数から結果の表示ができますか？

仕様上は各パターンについて 2 回以上の配信数がある場合に表示できます。しかし、配信数が少ない場合には結果が変わりやすいため、ある程度の期間を経てから判断することを推奨します。

---

## 有意差とはなんですか？

対象となる指標 (CVRや開封率、ボタン押下率など) について統計的な処理を行い、対象になる指標の差が偶然によらないものであるかを判定したものです。
計算には [t検定](https://en.wikipedia.org/wiki/Welch%27s_t-test) を用いています。
詳細は例えば [Statistical inference](https://en.wikipedia.org/wiki/Statistical_inference) を参照ください。

---

## 有意差ありとでたらそれ以降で判定結果は変わりませんか？

変わりえます。配信開始直後など、配信数が少ない場合には判定結果は変化しやすいためです。

---

## 過去の有意差は見られますか？

過去の時点の結果を遡ってみることはできません。

---

## 信頼区間で用いている有意水準 (信頼水準) は変更できますか？

有意水準を変更することはできません。

---

## リクエスト実行状況を意識して、APIを利用する必要はありますか？

ReproのAPIは単位時間あたりのリクエスト数に上限（Rate Limit）があり、上限を超えると `429 Too Many Requests` エラーが返ります。
そのため、アクセス上限を考慮したリクエスト設計が重要です。

### 上限の仕様

機能ごとに単位時間あたりのアクセス上限は異なります。
それぞれ以下のとおりです。

| 機能名 | アクセス上限 |
| --- | --- |
| オーディエンスAPI | APIトークンごとに10分あたり15件 |
| プッシュAPI | APIトークンごとに1分あたり1000件 |
| ユーザープロフィールAPI | APIトークンごとに1分あたり1000件 |
| ユーザープロフィールバルクインポートAPI v3 | APIトークンごとに10分あたり10件 |
| 削除ユーザー登録API | APIトークンごとに1分あたり1000件 |
| ニュースフィードAPI | Clientトークンごとに1分あたり3000件 |

##### NOTE
アクセス上限設定値は、機能単位でのAPIトークンごととなります。
例えば、プッシュAPIとユーザープロフィールAPIは同じAPIトークンを利用していますが、別機能のため同時にリクエストしたとしても、それぞれ1件ずつのカウントとなります。

リクエスト数がアクセス上限を超えると、 `HTTP Status 429 (Too Many Requests)` が返ります。

### 上限に対する現在の使用状況

APIレスポンスに含まれる以下のHTTPヘッダーを使用して、現在の使用状況を監視できます。

| ヘッダー名 | 説明 |
| --- | --- |
| `X-RateLimit-Limit` | 単位時間あたりのアクセス上限 |
| `X-RateLimit-Remaining` | アクセスできる残り回数 |
| `X-RateLimit-Reset` | アクセス数がリセットされる時刻(unixtime) |
| `Retry-After` | 再実行可能になるまでの秒数 |

### 上限への対処法

APIレスポンスに含まれるHTTPヘッダーをもとに事前に制御することと、上限エラーに適切に対応することの両方があり、どちらも対応することをお勧めします。

#### 上限に達する前の対処

`X-RateLimit-Remaining` と `X-RateLimit-Reset` をもとに、リクエスト数が上限を超えないよう制御してください。

- `Remaining` が少なくなってきた場合は、リクエスト間隔をあける
- `Reset` 時刻まで待機することで、上限超過を防ぐ
- 短時間にリクエストを集中させない
- 可能な場合はリクエストをまとめる

#### 上限に達した場合の対処

アクセス上限を超え、 `429 Too Many Requests` が返った場合は `Retry-After` をもとに、リトライ処理を行ってください。

- `Retry-After` の値を参考に一定時間待機する
- 再度 `429 Too Many Requests` が発生した場合は、さらに待機してリトライする
- 短時間での連続リトライは避ける

##### WARNING
`429 Too Many Requests` が返った場合は、 `Retry-After` の秒数より、1秒以上は待機時間を延ばしてください。
`Retry-After` の秒数を待ってリクエストを行った場合でも、再実行可能になるまでコンマ秒足りずに再度 `429 Too Many Requests` が返ることがあります。

---

## アプリ利用ユーザーへデータ取得の許諾を取る必要はありますか？

アプリユーザーの行動データを取得するためには、ユーザーからそれに対する許諾を得る必要があります。
詳しくはReproの [利用規約](https://repro.io/company/legal/term/) をご覧ください。

---

## Reproから来る通知メールをOFFにできますか？

**設定 > メール通知** からオン/オフを切り替えることができます。メールでは以下の内容が通知されます。

- [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md) の設定数が上限に達した場合
- [ユーザープロフィールバルクインポート](https://docs.repro.io/ja/dev/user-profile-bulk-import-api/index.md) の更新情報
- [プッシュ通知](https://docs.repro.io/ja/dashboard/campaign/push-notification.md) の配信が中断された場合
- [オーディエンス](https://docs.repro.io/ja/dashboard/campaign/audience.md) のインポートが完了した場合

---

## 配信対象設定で利用できるマーケティング機能関連のイベントは何がありますか？

本来、 [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md) を行いて実装し、ユーザーがイベントを実行すると、配信対象設定のフィルター条件に指定できるようになります。

それ以外に、Reproがマーケティング機能の利用に伴い、自動でトラッキングするイベントが存在します。
これらのイベントは、SDKを用いた実装は不要で利用できます。

トラッキングの定義は、以下のとおりです。

※β版機能で使用可能なイベントがある場合がありますので、お問い合わせください。

### プッシュ通知 配信

プッシュ通知が対象の端末に配信された（ReproサーバーからAPNsやFCMへのリクエストが正常に受理された）ことを示す。

※コントロールグループの場合は、その端末に配信可能であったかに関わらずイベントが記録される。

| プロパティ名 | データ例 | 説明 |
| --- | --- | --- |
| campaign_id | 1234567 | キャンペーン情報を示す。「セールのお知らせ」など、Repro管理画面に作成いただくキャンペーン単位でID(数値)が発番され、途中で変わることはない |

### プッシュ通知 開封

プッシュ通知が対象の端末で開封されたことを示す。

※管理画面上のみなし開封定義では記録されず、直接通知をタップしてアプリを起動した場合のみ記録されます

| プロパティ名 | データ例 | 説明 |
| --- | --- | --- |
| campaign_id | 1234567 | キャンペーン情報を示す。「セールのお知らせ」など、Repro管理画面に作成いただくキャンペーン単位でID(数値)が発番され、途中で変わることはない |

### WEBプッシュ通知 配信

ReproサーバーからWebプッシュ配信エンドポイントへのリクエストが成功したことを示す。

| プロパティ名 | データ例 | 説明 |
| --- | --- | --- |
| campaign_id | 1234567 | キャンペーン情報を示す。「セールのお知らせ」など、Repro管理画面に作成いただくキャンペーン単位でID(数値)が発番され、途中で変わることはない |

### WEBプッシュ通知 表示

Webプッシュ通知が表示されたことを示す。

| プロパティ名 | データ例 | 説明 |
| --- | --- | --- |
| campaign_id | 1234567 | キャンペーン情報を示す。「セールのお知らせ」など、Repro管理画面に作成いただくキャンペーン単位でID(数値)が発番され、途中で変わることはない |

### WEBプッシュ通知 開封

Webプッシュ通知が開封されたことを示す。

| プロパティ名 | データ例 | 説明 |
| --- | --- | --- |
| campaign_id | 1234567 | キャンペーン情報を示す。「セールのお知らせ」など、Repro管理画面に作成いただくキャンペーン単位でID(数値)が発番され、途中で変わることはない |

### アプリ内メッセージ 表示

アプリ内メッセージが表示されたことを示す。

※コントロールグループの場合は実際にメッセージを表示していないデータも含む。

| プロパティ名 | データ例 | 説明 |
| --- | --- | --- |
| in_app_message_id | 1234567 | キャンペーン情報を示す。「セールのお知らせ」など、Repro管理画面に作成いただくキャンペーン単位でID(数値)が発番され、途中で変わることはない |

### アプリ内メッセージ ボタンクリック

アプリ内メッセージ内のアクションボタンがクリックされたことを示す。(閉じるボタン含む)

※コントロールグループの場合はメッセージが閉じた扱いになるデータも含む。

| プロパティ名 | データ例 | 説明 |
| --- | --- | --- |
| in_app_message_id | 1234567 | キャンペーン情報を示す。「セールのお知らせ」など、Repro管理画面に作成いただくキャンペーン単位でID(数値)が発番され、途中で変わることはない |

### WEBメッセージ 表示

Webメッセージが表示されたことを示す。

※コントロールグループの場合は実際にメッセージを表示していないデータも含む。

| プロパティ名 | データ例 | 説明 |
| --- | --- | --- |
| web_message_id | 1234567 | キャンペーン情報を示す。「セールのお知らせ」など、Repro管理画面に作成いただくキャンペーン単位でID(数値)が発番され、途中で変わることはない |

### WEBメッセージ ボタンクリック

Webメッセージ内のアクションボタンがクリックされたことを示す(閉じるボタン含む)。

※コントロールグループの場合はメッセージが閉じた扱いになるデータも含む。

| プロパティ名 | データ例 | 説明 |
| --- | --- | --- |
| web_message_id | 1234567 | キャンペーン情報を示す。「セールのお知らせ」など、Repro管理画面に作成いただくキャンペーン単位でID(数値)が発番され、途中で変わることはない |

### メール 配信

Reproサーバーからメールベンダーに送信依頼を行ったメールが正常にメール配信したことを示す。

| プロパティ名 | データ例 | 説明 |
| --- | --- | --- |
| campaign_id | 1234567 | キャンペーン情報を示す。「セールのお知らせ」など、Repro管理画面に作成いただくキャンペーン単位でID(数値)が発番され、途中で変わることはない |

### メール 開封

メールが開封されたことを示す。

| プロパティ名 | データ例 | 説明 |
| --- | --- | --- |
| campaign_id | 1234567 | キャンペーン情報を示す。「セールのお知らせ」など、Repro管理画面に作成いただくキャンペーン単位でID(数値)が発番され、途中で変わることはない |

### メール内リンク クリック

メール内のリンクがクリックされたことを示す。

| プロパティ名 | データ例 | 説明 |
| --- | --- | --- |
| campaign_id | 1234567 | キャンペーン情報を示す。「セールのお知らせ」など、Repro管理画面に作成いただくキャンペーン単位でID(数値)が発番され、途中で変わることはない |

### メール 配信失敗

Reproサーバーからメールベンダーに送信依頼を行ったメールのうち、ハードバウンス等の理由で配信を行わなかったことを示す。

※ハードバウンスとは メールアドレスが存在しない、受信者側のメールを拒否しているなど、次回以降届く見込みがないメールアドレスのことを指します。

| プロパティ名 | データ例 | 説明 |
| --- | --- | --- |
| campaign_id | 1234567 | キャンペーン情報を示す。「セールのお知らせ」など、Repro管理画面に作成いただくキャンペーン単位でID(数値)が発番され、途中で変わることはない |

### メール 購読解除

Reproが用意した購読解除URLや、Gmail等のメーラーが用意したワンクリック購読解除をクリックし、メールの購読解除を行ったことを示す。

| プロパティ名 | データ例 | 説明 |
| --- | --- | --- |
| campaign_id | 1234567 | キャンペーン情報を示す。「セールのお知らせ」など、Repro管理画面に作成いただくキャンペーン単位でID(数値)が発番され、途中で変わることはない |

---

## シルバーエッグレコメンドメッセージ

### シルバーエッグレコメンドメッセージとは

[シルバーエッグ・テクノロジー社のレコメンドサービス（アイジェント・レコメンダー）](https://www.silveregg.co.jp/service/recommender.html) とReproを連携し、Reproのメッセージでレコメンデーションを利用することができる機能です。
ご利用については、弊社カスタマーサクセス担当までご連絡ください。

#### シルバーエッグレコメンドメッセージでできること

連携によって、商品ページの下の方までスクロールしなければ見れないレコメンド情報を、画面上の好きな位置に、自由なタイミングで、特定のユーザーにセグメントしてメッセージとして表示できるようになります。
また、ページの特徴に合わせて「レコメンドのタイプ」を変更したり、効果的なレコメンドのタイプを検証するために、種類別の複数パターンを作ってA/Bテストを実施することも可能です。

### シルバーエッグレコメンドメッセージ利用の流れ

シルバーエッグレコメンドメッセージのご利用は、以下の流れとなります

1. シルバーエッグ・テクノロジー社と契約を行う
2. 弊社営業、もしくはカスタムーサクセス担当者を通じて、シルバーエッグレコメンドメッセージの利用申請を行う
3. 管理画面上で必要項目を設定する
4. 実装を追加する
5. キャンペーンを作成する

##### WARNING
アプリ内メッセージのシルバーエッグレコメンドメッセージを利用する場合は、以下のRepro SDKを利用する必要があります

- iOS: 5.3.0 以上
- Android: 5.2.0 以上

##### NOTE
- 1 に関しては、シルバーエッグ・テクノロジー社のアイジェント・レコメンダーが利用可能な状態であることを前提としております。



### 管理画面上で必要項目を設定する

シルバーエッグメッセージを利用するには、まずプラグイン設定で連携に必要な項目を設定します。



サイドメニューのプラグインという項目をクリックします。



クリック後に **Silver Egg設定** という画面が表示されるので、シルバーエッグ・テクノロジー社から提供された、 `マーチャントID` と `接続先ドメイン` を入力します。

##### NOTE
- `接続先ドメイン` はシルバーエッグ・テクノロジー社から指定されたドメインを入力してください。
- 本設定を完了しないと、シルバーエッグレコメンデーションメッセージを表示することはできません。

### 実装を追加する

Web向け SDKをご利用のお客様は [Setup / ユーザーID](https://docs.repro.io/ja/dev/web/api.md) を参考に、追加の実装を行ってください。
モバイルアプリ向け SDKをご利用のお客様は、 [シルバーエッグレコメンドメッセージの開発ガイド](https://docs.repro.io/ja/dev/sdk/silver-egg-recommend-in-app-message.md) をご確認ください。

### キャンペーンを作成する



#### テンプレートの選択

**マーケティング > メッセージ** に行き、 新規作成ボタンから Webメッセージ もしくは アプリ内メッセージ をクリックしてください。
テンプレート選択画面にシルバーエッグレコメンド専用のメッセージテンプレートが追加されていますので、このテンプレートを利用してメッセージを作成します。





#### キャンペーンの設定

シルバーエッグレコメンドメッセージの設定項目として、以下の項目が設定可能です。



**（Web メッセージのみ）メッセージの位置**
: - メッセージの表示位置を左上、上、右上、左、中央、右、左下、下、右下のいずれかに設定することができます。この項目はWebメッセージのみ指定可能となっており、アプリ内メッセージでは指定できません。

**Overlayの有無**
: - メッセージを表示する際に、画面全体を要素（オーバーレイ）で覆うかどうかを選択できます。オーバーレイをつけることでユーザーの動きを止めてメッセージに注目してもらうことができます。また、オーバーレイで覆われた画面をクリックすると、メッセージとオーバーレイのどちらも非表示となります。

**閉じるボタンの有無**
: - メッセージを閉じるボタン（メッセージの右上に配置）の表示有無を選択できます。閉じるボタンを表示しない場合でも、オーバーレイを設定していればユーザーはメッセージを非表示にすることができます。

**背景色**
: - オーバーレイの背景色と、ダイアログ部分の背景色、閉じるボタンの背景色を個別に指定します。なお、閉じるボタンは背景色だけでなく、アイコンの色も指定可能です。

**見出し（任意）**
: - メッセージのヘッダーを指定します。テキストの色を指定できます。

**本文**
: - メッセージの本文を指定します。テキストの色を指定できます。

**（アプリ内メッセージのみ）アクションボタン**
: - アクションボタンに表示するテキストを指定します。ボタンの背景色とテキストの色を指定できます。

**（アプリ内メッセージのみ）トラッキングイベント名（任意）**
: - トラッキングイベント名を指定すると、アクションボタンをクリックしたときに計測されるイベントを変更することができます。

**商品名**
: - シルバーエッグ・テクノロジー社からレコメンドされたアイテム（商品名）の色を指定できます。ただし、アイテム名の色を1つずつ指定することはできません。

**価格**
: - シルバーエッグ・テクノロジー社からレコメンドされたアイテム（価格）の色を指定できます。ただし、アイテム名の色を1つずつ指定することはできません。

**SpecID**
: - シルバーエッグ・テクノロジー社から提供されるレコメンドのタイプや表示するページなどが設定された `SpecID` を入力します。

##### NOTE
- SpecIDについて不明点があれば、シルバーエッグ・テクノロジー社の担当者へご確認ください。
- メッセージ内の画像やボタンには、弊社SDKがシルバーエッグ・テクノロジー社にレコメンドアイテムをリクエストした際にレスポンスされる `deeplink` が、クリックしたときに遷移するURLとして自動で設定されます。 `deeplink` に具体的にどのような値が設定されているかは、シルバーエッグ・テクノロジー社の担当者へご確認ください。



#### レコメンドのタイプについて

`SpecID` で指定できるレコメンドのタイプについては以下の4つから選択します。

| レコメンドタイプ | 例 |
| --- | --- |
| 閲覧閲覧相関 (Browse-Browse) | この商品を見た人は、こんな商品も見ています |
| 同時購買相関 (Order-Order) | この商品を購入した人は、一緒にこんな商品を購入しています |
| 閲覧購買相関 (Browse-Order) | この商品を見た人は、結果的にこんな商品を購入しています |
| 過去購買相関 (Past-Order) | この商品を購入した人は、次にこんな商品を購入しています |

詳細はシルバーエッグ・テクノロジー社から提供される資料をご確認ください。



#### メッセージのカスタマイズ

シルバーエッグレコメンドメッセージでは、カスタムWebメッセージと HTMLアプリ内メッセージも利用可能です。
利用方法については [カスタムメッセージ](https://docs.repro.io/ja/dashboard/campaign/custom-message.md)、[HTMLアプリ内メッセージ](https://docs.repro.io/ja/dashboard/campaign/html-in-app-message.md)  の項目をご確認ください。

##### NOTE
シルバーエッグレコメンドメッセージ内でカスタムメッセージを利用される場合は誤って data-repro--wrapper 属性を消去しないようにご注意ください。メッセージ表示が正しく行われません。



#### その他の設定について

配信設定などのその他のメッセージ設定につきましては、 [Webメッセージ](https://docs.repro.io/ja/dashboard/campaign/web-message.md)、[アプリ内メッセージ](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md) の項目をご確認ください。

---

## 管理画面ガイド

* [アナリティクス](https://docs.repro.io/ja/dashboard/analytics/index.md)
  * [リテンション分析](https://docs.repro.io/ja/dashboard/analytics/retention-analysis.md)
  * [アクセス分析](https://docs.repro.io/ja/dashboard/analytics/access-summary.md)
  * [KPI分析](https://docs.repro.io/ja/dashboard/analytics/kpi-analysis.md)
  * [ファネル分析](https://docs.repro.io/ja/dashboard/analytics/funnel-analysis.md)
  * [フィルターを追加](https://docs.repro.io/ja/dashboard/analytics/filter.md)
* [マーケティング](https://docs.repro.io/ja/dashboard/campaign/index.md)
  * [プッシュ通知](https://docs.repro.io/ja/dashboard/campaign/push-notification.md)
  * [イベント起点プッシュ通知](https://docs.repro.io/ja/dashboard/campaign/event-based-push-notification.md)
  * [アプリ内メッセージ](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md)
  * [HTMLアプリ内メッセージ](https://docs.repro.io/ja/dashboard/campaign/html-in-app-message.md)
  * [Webメッセージ](https://docs.repro.io/ja/dashboard/campaign/web-message.md)
  * [カスタムメッセージ](https://docs.repro.io/ja/dashboard/campaign/custom-message.md)
  * [カスタムJavaScript](https://docs.repro.io/ja/dashboard/campaign/custom-js.md)
  * [カスタムメッセージで利用可能なHTMLタグ・属性](https://docs.repro.io/ja/dashboard/campaign/available-tags.md)
  * [シルバーエッグレコメンドメッセージ](https://docs.repro.io/ja/dashboard/campaign/silver-egg-recommend-message.md)
  * [閲覧人数表示](https://docs.repro.io/ja/dashboard/campaign/social-proof.md)
  * [Webプッシュ通知](https://docs.repro.io/ja/dashboard/campaign/web-push-notification.md)
  * [アプリ内パラメーター](https://docs.repro.io/ja/dashboard/campaign/remote-config.md)
  * [オーディエンス](https://docs.repro.io/ja/dashboard/campaign/audience.md)
  * [シナリオ](https://docs.repro.io/ja/dashboard/campaign/scenario.md)
  * [変数の挿入](https://docs.repro.io/ja/dashboard/campaign/insert-variable.md)
  * [Liquidによるパーソナライズ](https://docs.repro.io/ja/dashboard/campaign/liquid-personalization.md)
  * [インセンティブコード管理機能](https://docs.repro.io/ja/dashboard/campaign/incentive-code-management.md)
  * [メール](https://docs.repro.io/ja/dashboard/campaign/mail/index.md)
  * [LINEメッセージ(β)](https://docs.repro.io/ja/dashboard/campaign/line-message.md)
  * [ニュースフィード](https://docs.repro.io/ja/dashboard/campaign/newsfeed.md)
* [データエクスポート](https://docs.repro.io/ja/dashboard/export/index.md)
  * [イベントデータエクスポート](https://docs.repro.io/ja/dashboard/export/event-data-export.md)
  * [ユーザーIDエクスポート](https://docs.repro.io/ja/dashboard/export/userid-export.md)
* [イベント](https://docs.repro.io/ja/dashboard/event/index.md)
  * [イベント設定](https://docs.repro.io/ja/dashboard/event/event-settings.md)
* [ユーザープロフィール](https://docs.repro.io/ja/dashboard/user-profile/index.md)
  * [ユーザープロフィール設定](https://docs.repro.io/ja/dashboard/user-profile/user-profile-settings.md)
* [設定](https://docs.repro.io/ja/dashboard/setting/index.md)
  * [プロジェクト設定](https://docs.repro.io/ja/dashboard/setting/project-setting.md)
  * [Web設定](https://docs.repro.io/ja/dashboard/setting/web-tracking-rule.md)
  * [メンバー管理](https://docs.repro.io/ja/dashboard/setting/manage-members.md)
  * [LINEチャネル設定](https://docs.repro.io/ja/dashboard/setting/line-channel-setting.md)
  * [ReproへのLINEユーザーIDの登録](https://docs.repro.io/ja/dashboard/setting/line-user-import.md)
  * [セキュリティ設定](https://docs.repro.io/ja/dashboard/setting/security-setting.md)
* [アカウント](https://docs.repro.io/ja/dashboard/account/index.md)
  * [アカウントロック](https://docs.repro.io/ja/dashboard/account/index.md#id2)
  * [Googleログイン](https://docs.repro.io/ja/dashboard/account/index.md#google)
  * [2要素認証](https://docs.repro.io/ja/dashboard/account/index.md#id3)
  * [パスワード要件](https://docs.repro.io/ja/dashboard/account/index.md#id4)
  * [ログイン状態保持期間](https://docs.repro.io/ja/dashboard/account/index.md#id5)
* [その他](https://docs.repro.io/ja/dashboard/misc/index.md)
  * [ユーザーの定義](https://docs.repro.io/ja/dashboard/misc/user-definition.md)
  * [データポイント](https://docs.repro.io/ja/dashboard/misc/datapoints.md)
  * [データの更新タイミング](https://docs.repro.io/ja/dashboard/misc/aggregation.md)
  * [データ保存期間](https://docs.repro.io/ja/dashboard/misc/data-retention-period.md)
  * [CSVエクスポート](https://docs.repro.io/ja/dashboard/misc/csv-export.md)
  * [メールの配信上限](https://docs.repro.io/ja/dashboard/misc/mail/sending-quota.md)

---

## アナリティクス

* [リテンション分析](https://docs.repro.io/ja/dashboard/analytics/retention-analysis.md)
* [アクセス分析](https://docs.repro.io/ja/dashboard/analytics/access-summary.md)
* [KPI分析](https://docs.repro.io/ja/dashboard/analytics/kpi-analysis.md)
* [ファネル分析](https://docs.repro.io/ja/dashboard/analytics/funnel-analysis.md)
* [フィルターを追加](https://docs.repro.io/ja/dashboard/analytics/filter.md)

---

## マーケティング

* [プッシュ通知](https://docs.repro.io/ja/dashboard/campaign/push-notification.md)
  * [プッシュ通知を有効にする](https://docs.repro.io/ja/dashboard/campaign/push-notification.md#id2)
  * [プッシュ通知作成画面](https://docs.repro.io/ja/dashboard/campaign/push-notification.md#push-create-message)
  * [プッシュ通知配信結果画面](https://docs.repro.io/ja/dashboard/campaign/push-notification.md#id18)
  * [使用事例：A/Bテストの実装](https://docs.repro.io/ja/dashboard/campaign/push-notification.md#a-b)
  * [許諾率を確認する](https://docs.repro.io/ja/dashboard/campaign/push-notification.md#push-enabled-rate)
* [イベント起点プッシュ通知](https://docs.repro.io/ja/dashboard/campaign/event-based-push-notification.md)
  * [イベント起点プッシュ通知を作成する](https://docs.repro.io/ja/dashboard/campaign/event-based-push-notification.md#id2)
  * [効果測定](https://docs.repro.io/ja/dashboard/campaign/event-based-push-notification.md#id9)
  * [A/Bテスト](https://docs.repro.io/ja/dashboard/campaign/event-based-push-notification.md#a-b)
  * [よくあるご質問](https://docs.repro.io/ja/dashboard/campaign/event-based-push-notification.md#id15)
* [アプリ内メッセージ](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md)
  * [アプリ内メッセージを作成する](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md#id2)
  * [コンテンツを作成する](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md#inapp-versions)
  * [キャンペーンをニュースフィードとして利用する](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md#id17)
  * [配信対象者を各パターンに振り分ける](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md#id18)
  * [配信設定](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md#in-app-message-delivery)
  * [メッセージ表示トリガー](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md#in-app-message-trigger)
  * [配信対象を選択する](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md#inapp-select-target)
  * [下書きとして保存](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md#inapp-save-as-draft)
  * [公開、もしくは、非公開にする](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md#inapp-launch-as-public)
  * [効果測定](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md#inapp-measurement)
  * [A/Bテスト](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md#a-b)
* [HTMLアプリ内メッセージ](https://docs.repro.io/ja/dashboard/campaign/html-in-app-message.md)
  * [HTMLアプリ内メッセージを作成する](https://docs.repro.io/ja/dashboard/campaign/html-in-app-message.md#id1)
  * [HTMLアプリ内メッセージを編集する](https://docs.repro.io/ja/dashboard/campaign/html-in-app-message.md#id4)
  * [コンテンツを編集する](https://docs.repro.io/ja/dashboard/campaign/html-in-app-message.md#html-inapp-message-contents)
  * [HTMLアプリ内メッセージでJavaScriptを利用する](https://docs.repro.io/ja/dashboard/campaign/html-in-app-message.md#htmljavascript)
  * [HTMLアプリ内メッセージで動画を再生する](https://docs.repro.io/ja/dashboard/campaign/html-in-app-message.md#id14)
  * [その他の設定](https://docs.repro.io/ja/dashboard/campaign/html-in-app-message.md#id15)
* [Webメッセージ](https://docs.repro.io/ja/dashboard/campaign/web-message.md)
  * [Webメッセージを作成する](https://docs.repro.io/ja/dashboard/campaign/web-message.md#id1)
  * [メッセージの表示タイミングを選択](https://docs.repro.io/ja/dashboard/campaign/web-message.md#web-message-timming)
  * [表示位置](https://docs.repro.io/ja/dashboard/campaign/web-message.md#web-message-position)
  * [コンテンツを作成する](https://docs.repro.io/ja/dashboard/campaign/web-message.md#web-message-versions)
  * [キャンペーンをニュースフィードとして利用する](https://docs.repro.io/ja/dashboard/campaign/web-message.md#id53)
  * [カスタムメッセージ](https://docs.repro.io/ja/dashboard/campaign/web-message.md#web-message-variant-distribution)
  * [配信対象者を各パターンに振り分ける](https://docs.repro.io/ja/dashboard/campaign/web-message.md#id56)
  * [配信設定](https://docs.repro.io/ja/dashboard/campaign/web-message.md#web-message-delivery)
  * [メッセージ表示トリガー](https://docs.repro.io/ja/dashboard/campaign/web-message.md#web-message-display-trigger)
  * [配信対象設定](https://docs.repro.io/ja/dashboard/campaign/web-message.md#web-message-select-target)
  * [下書きとして保存](https://docs.repro.io/ja/dashboard/campaign/web-message.md#web-message-save-as-draft)
  * [公開、もしくは、非公開にする](https://docs.repro.io/ja/dashboard/campaign/web-message.md#web-message-launch-as-public)
  * [効果測定](https://docs.repro.io/ja/dashboard/campaign/web-message.md#web-message-measurement)
  * [A/Bテスト](https://docs.repro.io/ja/dashboard/campaign/web-message.md#a-b)
* [カスタムメッセージ](https://docs.repro.io/ja/dashboard/campaign/custom-message.md)
  * [カスタムメッセージを作成する](https://docs.repro.io/ja/dashboard/campaign/custom-message.md#id2)
  * [カスタムメッセージを編集する](https://docs.repro.io/ja/dashboard/campaign/custom-message.md#id5)
  * [コンテンツを編集する](https://docs.repro.io/ja/dashboard/campaign/custom-message.md#custom-message-contents)
  * [その他の設定](https://docs.repro.io/ja/dashboard/campaign/custom-message.md#id14)
* [カスタムJavaScript](https://docs.repro.io/ja/dashboard/campaign/custom-js.md)
  * [カスタムJavaScriptとは？](https://docs.repro.io/ja/dashboard/campaign/custom-js.md#id1)
  * [導入手順](https://docs.repro.io/ja/dashboard/campaign/custom-js.md#id2)
  * [実装例](https://docs.repro.io/ja/dashboard/campaign/custom-js.md#custom-js-sample)
  * [セキュリティに関するTips](https://docs.repro.io/ja/dashboard/campaign/custom-js.md#tips)
  * [効果測定に関する注意点](https://docs.repro.io/ja/dashboard/campaign/custom-js.md#id10)
  * [その他の注意点](https://docs.repro.io/ja/dashboard/campaign/custom-js.md#id11)
* [カスタムメッセージで利用可能なHTMLタグ・属性](https://docs.repro.io/ja/dashboard/campaign/available-tags.md)
  * [任意のタグの中で利用可能な属性](https://docs.repro.io/ja/dashboard/campaign/available-tags.md#id1)
  * [利用可能なタグと属性の一覧表](https://docs.repro.io/ja/dashboard/campaign/available-tags.md#id2)
* [シルバーエッグレコメンドメッセージ](https://docs.repro.io/ja/dashboard/campaign/silver-egg-recommend-message.md)
  * [シルバーエッグレコメンドメッセージとは](https://docs.repro.io/ja/dashboard/campaign/silver-egg-recommend-message.md#id2)
  * [シルバーエッグレコメンドメッセージ利用の流れ](https://docs.repro.io/ja/dashboard/campaign/silver-egg-recommend-message.md#id5)
  * [管理画面上で必要項目を設定する](https://docs.repro.io/ja/dashboard/campaign/silver-egg-recommend-message.md#silver-egg-recommend-message-plugin)
  * [実装を追加する](https://docs.repro.io/ja/dashboard/campaign/silver-egg-recommend-message.md#id7)
  * [キャンペーンを作成する](https://docs.repro.io/ja/dashboard/campaign/silver-egg-recommend-message.md#id8)
* [閲覧人数表示](https://docs.repro.io/ja/dashboard/campaign/social-proof.md)
  * [閲覧人数表示の仕組み](https://docs.repro.io/ja/dashboard/campaign/social-proof.md#id2)
  * [閲覧人数表示の使い方](https://docs.repro.io/ja/dashboard/campaign/social-proof.md#web-message-version-social-proof)
* [Webプッシュ通知](https://docs.repro.io/ja/dashboard/campaign/web-push-notification.md)
  * [対応ブラウザ](https://docs.repro.io/ja/dashboard/campaign/web-push-notification.md#id1)
  * [導入手順](https://docs.repro.io/ja/dashboard/campaign/web-push-notification.md#id2)
  * [Webプッシュ通知の作成と配信](https://docs.repro.io/ja/dashboard/campaign/web-push-notification.md#id3)
  * [プレビューで確認する](https://docs.repro.io/ja/dashboard/campaign/web-push-notification.md#id24)
  * [効果測定](https://docs.repro.io/ja/dashboard/campaign/web-push-notification.md#web-push-measurement)
* [アプリ内パラメーター](https://docs.repro.io/ja/dashboard/campaign/remote-config.md)
  * [アプリ内パラメーターでできること](https://docs.repro.io/ja/dashboard/campaign/remote-config.md#id2)
  * [アプリ内パラメーターの仕組み](https://docs.repro.io/ja/dashboard/campaign/remote-config.md#id3)
  * [アプリ内パラメーターの制約](https://docs.repro.io/ja/dashboard/campaign/remote-config.md#id5)
  * [アプリ内パラメーターを作成する](https://docs.repro.io/ja/dashboard/campaign/remote-config.md#id6)
* [オーディエンス](https://docs.repro.io/ja/dashboard/campaign/audience.md)
  * [オーディエンスの種類](https://docs.repro.io/ja/dashboard/campaign/audience.md#id2)
  * [オーディエンスを作成する](https://docs.repro.io/ja/dashboard/campaign/audience.md#id3)
  * [作成結果の確認](https://docs.repro.io/ja/dashboard/campaign/audience.md#id31)
  * [対象ユーザー数の更新](https://docs.repro.io/ja/dashboard/campaign/audience.md#id34)
  * [オーディエンスを削除する](https://docs.repro.io/ja/dashboard/campaign/audience.md#id35)
* [シナリオ](https://docs.repro.io/ja/dashboard/campaign/scenario.md)
  * [シナリオをはじめる前に](https://docs.repro.io/ja/dashboard/campaign/scenario.md#id2)
  * [シナリオを作成する](https://docs.repro.io/ja/dashboard/campaign/scenario.md#id3)
  * [配信結果を確認する](https://docs.repro.io/ja/dashboard/campaign/scenario.md#id12)
  * [配信条件と配信結果に関する注意事項](https://docs.repro.io/ja/dashboard/campaign/scenario.md#id18)
  * [シナリオ一覧画面を確認する](https://docs.repro.io/ja/dashboard/campaign/scenario.md#id19)
* [変数の挿入](https://docs.repro.io/ja/dashboard/campaign/insert-variable.md)
  * [概要](https://docs.repro.io/ja/dashboard/campaign/insert-variable.md#id2)
  * [具体的なユースケース例](https://docs.repro.io/ja/dashboard/campaign/insert-variable.md#id3)
  * [チャネルごとの対応状況](https://docs.repro.io/ja/dashboard/campaign/insert-variable.md#id4)
  * [プッシュ通知でのパーソナライズ施策の作成](https://docs.repro.io/ja/dashboard/campaign/insert-variable.md#id8)
  * [プッシュ通知作成](https://docs.repro.io/ja/dashboard/campaign/insert-variable.md#id10)
  * [配信対象設定](https://docs.repro.io/ja/dashboard/campaign/insert-variable.md#id17)
  * [下書き保存したメッセージを複製し、テスター向けにテスト配信を行う](https://docs.repro.io/ja/dashboard/campaign/insert-variable.md#id18)
  * [下書きメッセージを公開](https://docs.repro.io/ja/dashboard/campaign/insert-variable.md#id19)
  * [アプリ内メッセージ、Webメッセージでのパーソナライズ施策の作成](https://docs.repro.io/ja/dashboard/campaign/insert-variable.md#id20)
  * [メッセージ作成](https://docs.repro.io/ja/dashboard/campaign/insert-variable.md#id21)
* [Liquidによるパーソナライズ](https://docs.repro.io/ja/dashboard/campaign/liquid-personalization.md)
  * [概要](https://docs.repro.io/ja/dashboard/campaign/liquid-personalization.md#id1)
  * [Liquidとは](https://docs.repro.io/ja/dashboard/campaign/liquid-personalization.md#id2)
  * [プッシュ通知でのLiquid利用時の注意事項](https://docs.repro.io/ja/dashboard/campaign/liquid-personalization.md#id3)
  * [アプリ内メッセージ、WebメッセージでのLiquid利用時の注意事項](https://docs.repro.io/ja/dashboard/campaign/liquid-personalization.md#webliquid)
* [インセンティブコード管理機能](https://docs.repro.io/ja/dashboard/campaign/incentive-code-management.md)
  * [具体的なユースケース例](https://docs.repro.io/ja/dashboard/campaign/incentive-code-management.md#id2)
  * [インセンティブコードのインポート](https://docs.repro.io/ja/dashboard/campaign/incentive-code-management.md#id3)
  * [割り当てルールについて](https://docs.repro.io/ja/dashboard/campaign/incentive-code-management.md#id4)
  * [アプリ内メッセージ作成](https://docs.repro.io/ja/dashboard/campaign/incentive-code-management.md#id6)
  * [Webメッセージ作成](https://docs.repro.io/ja/dashboard/campaign/incentive-code-management.md#web)
* [メール](https://docs.repro.io/ja/dashboard/campaign/mail/index.md)
  * [一斉配信メール](https://docs.repro.io/ja/dashboard/campaign/mail/broadcast-mail.md)
  * [トリガーメール](https://docs.repro.io/ja/dashboard/campaign/mail/trigger-mail.md)
  * [登録されたメールアドレスの指定方法](https://docs.repro.io/ja/dashboard/campaign/mail/email-address-selection.md)
* [LINEメッセージ(β)](https://docs.repro.io/ja/dashboard/campaign/line-message.md)
  * [LINEメッセージの配信に必要な手順](https://docs.repro.io/ja/dashboard/campaign/line-message.md#id1)
  * [LINEメッセージの新規作成](https://docs.repro.io/ja/dashboard/campaign/line-message.md#id3)
  * [コンテンツの内容を入力する](https://docs.repro.io/ja/dashboard/campaign/line-message.md#id16)
  * [配信する](https://docs.repro.io/ja/dashboard/campaign/line-message.md#id43)
  * [LINEメッセージのキャンペーンの効果測定を確認する](https://docs.repro.io/ja/dashboard/campaign/line-message.md#id44)
* [ニュースフィード](https://docs.repro.io/ja/dashboard/campaign/newsfeed.md)
  * [具体的なユースケース](https://docs.repro.io/ja/dashboard/campaign/newsfeed.md#id2)
  * [利用可能なチャネル一覧](https://docs.repro.io/ja/dashboard/campaign/newsfeed.md#id3)
  * [プッシュ通知でニュースフィードを有効にする](https://docs.repro.io/ja/dashboard/campaign/newsfeed.md#id4)
  * [アプリ内メッセージでニュースフィードを有効にする](https://docs.repro.io/ja/dashboard/campaign/newsfeed.md#id5)
  * [Webメッセージでニュースフィードを有効にする](https://docs.repro.io/ja/dashboard/campaign/newsfeed.md#web)
  * [利用方法](https://docs.repro.io/ja/dashboard/campaign/newsfeed.md#id6)

---

## イベント起点プッシュ通知

イベント起点プッシュ通知は、サービスを利用中のユーザーの行動をきっかけにして、プッシュ通知を配信する機能です。
これによって、サイト上のユーザー行動をベースにトリガー配信を行うことができます。

以下のようなユースケースで有用です。

- ユーザー情報（会員ステータス）の変化を捉え、通知を送りたい。
- 「商品カートに追加」後、購入完了せずに離脱したユーザーに対して、1時間後に購入完了を促す通知を送りたい。
- 会員登録をスタートしたが、完了していないユーザーに1時間後、通知を送りたい。

### イベント起点プッシュ通知を作成する

イベント起点プッシュ通知は、以下の手順で作成します。

1. [イベント起点プッシュ通知の作成画面に遷移](#move-to-create-page)
2. [キャンペーン情報を入力](#input-metadata)
3. [配信対象を入力](#input-target)
4. [配信設定を入力](#input-trigger)
5. [メッセージを入力](#input-messages)
6. [公開を押して配信開始](#publish-campaign)



#### イベント起点プッシュ通知の作成画面に遷移

管理画面にログインし、左メニューの「マーケティング」->「イベント起点プッシュ通知」をクリックし、イベント起点プッシュ通知一覧画面に遷移します。



##### NOTE
- もし「イベント起点プッシュ通知」が表示されていない場合は、弊社CSまでお問い合わせください。

一覧ページの表示後、右上の「新規作成」ボタンをクリックし、イベント起点プッシュ通知の作成画面に遷移します。





#### キャンペーン情報を入力

キャンペーンの名前とキャンペーンのゴール、キャンペーンの狙いと実施後の結果を入力します。
（キャンペーンのゴールとキャンペーンの狙いと実施後の結果は任意です）





#### 配信対象を入力

キャンペーンの配信対象を指定します。

##### NOTE
- 配信対象に「カート追加を1回以上」を指定し、トリガー条件も「カート追加」を指定した場合、「カート追加」を1回実行した時点でプッシュ通知が配信されます。2回実行時ではないので設定時にはご注意ください。
- なお、セグメンテーションに時間がかかる場合、その限りではありません。





#### 配信設定を入力

キャンペーンの配信設定を入力します。

- トリガー条件を入力します。プッシュ通知を配信する起点となるイベントやプロパティを指定することができます。
  - 最大5つまでのイベントをOR条件で指定できます。
  - プロフィールの変化をトリガー条件とすることはできません。
- 指定した起点イベントの実行後すぐに配信するか、一定時間経過後に配信するかを選択することができます。
  - ただし、すぐに配信する設定を行った場合も、サーバーの混雑状況により配信まで数分〜数十分かかる場合があります。
  - 経過時間は最短15分後から最大7日後まで指定できます。
- 配信期間を設定します。
  - キャンペーンの保存後、配信期間は変更できません。変更する場合は該当のキャンペーンを複製してください。
- 配信時間帯を設定します。夜中や早朝などの意図しない時間帯の配信を防ぐために、配信が可能な時間を設定することができます。
  - 設定した配信時間帯以外にプッシュ通知のトリガー条件のイベントが実行された場合、次の配信時間帯になった時点でプッシュ通知が配信されます。
  - 次の配信時間帯を待っている間にキャンペーンの配信期間を過ぎてしまった場合にはプッシュ通知は配信されません。
  - キャンペーンの保存後、配信時間帯は変更できません。変更する場合は該当のキャンペーンを複製してください。
- 意図しないユーザーへの配信を止めるために、配信をキャンセルするイベントを指定できます。
  - 配信直前やトリガー発火直後にキャンセルするイベントが発生した場合など、配信をキャンセルするイベントの実行タイミングによっては、そのまま配信されてしまう可能性があります。
- プッシュ通知が1日に何度も配信されることを防ぐため、配信頻度を設定できます。
  - 1日に何度も実行される可能性があるイベントをトリガー条件として登録する場合、プッシュ通知が大量に配信される場合があります。





#### メッセージを入力

プッシュ通知のメッセージ内容を入力します。





#### 公開を押して配信開始

公開することで、配信対象になったユーザーが、配信設定のトリガーのイベントをトラックした時に、プッシュ通知が配信されます。

### 効果測定

開封数やコンバージョン数といったイベント起点プッシュ通知の効果を確認できます。





#### 配信結果

**配信数**
: プッシュ通知許諾がONのユーザーに対する配信のうち、ReproサーバーからAPNsやFCMへのリクエストが正常に受理された数です。日次でユニークユーザー数を集計します。

**開封数**
: 開封したユーザー数を日次で集計し、合計した数です。開封数にはみなし開封数と直接開封数が含まれます。
   
  **みなし開封数**
  : 配信から1時間以内にアプリを起動したユーザーの数です。
   
  **直接開封数**
  : 通知を直接タップしてアプリを起動したユーザーの数です。

**コンバージョン数**
: イベント起点プッシュ通知の「開封」から1時間以内に、作成画面で指定したゴールを達成したユーザーの数を日次で集計し、合計した数です。
   
  この「開封」には、「みなし開封」・「直接開封」の両方が含まれます。

**コンバージョン率**
: コンバージョン数 / 配信数 です。

**結果の推移**
: キャンペーン実施期間中の配信数、開封数、コンバージョン数を日次で集計した結果をグラフとして出力しています。計測単位はユーザーです。

##### NOTE
配信時刻の1時間以内に通知をタップしアプリを起動した場合、直接開封のみに計上されみなし開封には計上されません



### A/Bテスト

配信対象に指定したユーザーに複数のパターンのメッセージを均等に出し分けることで、どのようなメッセージを配信すれば開封率やコンバージョン率が向上するのかを検証することができる機能です。

#### メッセージ作成

メッセージのパターンを2個以上作成することで、A/Bテストを行うことができます。


- メッセージは最大4パターンまで追加することができます。
- パターンの追加や削除は新規作成時のみ行うことができます。

#### 配信対象者を各パターンに振り分ける



パターンを2つ以上に設定した場合も、各パターンに配信対象者を振り分けられます。
各パターンの合計が100%になるように設定します。

**均等に振り分ける(コントロールグループなし)** をクリックすると、各パターンを均等に振り分けます。

##### NOTE
- 各パターンは **1%** ~ **100%** まで設定出来ます。
- 整数のみ設定出来ます。
- 振り分け設定は新規作成時のみ行うことが出来ます。
- 配信数の規模により、設定した割合と実際の配信数が乖離することがあります。



#### 効果測定（A/Bテスト）

**詳細画面**

配信からしばらくすると、イベント起点プッシュ通知の開封率、コンバージョン率がパターンごとに表示されます。



A/Bテストの実行中にはA/Bテストの実行結果が表示されます。ここでは各パターンを選択した指標 (CVR, 開封率) を用いて比較を行えます。



**パターン**

A/Bテストで送信を行う各パターンが表示されます。

**ベースライン**

A/Bテストで各パターンを比較する際に基準となるパターンをベースラインとして選択します。ベースラインを変更することで、様々なパターン間の比較ができます。

**対象となる指標**

A/Bテストで各パターンをベースラインと比較する際に用いる指標を選択します。指標には割合を表す値 (CVR, 開封率) が選択できます。また、一覧に表示する指標については編集画面から変更できます。

**90%信頼区間**

各パターンをベースラインと比較した場合の 90% 信頼区間が表示されます。90% 信頼区間そのものの意味については [FAQ](https://docs.repro.io/ja/faq/general/significant-difference/5.md) をご参照ください。ここでは代表的なパターンの読み取り方について示します。

パターン１：



このような表示の場合、パターンとベースラインとの差が有意であることを意味します。配信を開始してから十分な期間が経過している場合、勝ちパターンの決定へと進むことを推奨します。

パターン２：



このような表示の場合、パターンとベースラインとの差が有意ではないことを意味します。結果が出るまでもう少し待つか、配信を開始してから十分な期間が経過している場合、差がないものとして次のキャンペーンの開始を検討することを推奨します。

パターン３：



このような表示の場合、パターンとベースラインとの差が有意であることを意味します。このような表示しかない場合、ベースラインとして設定しているパターンを勝ちパターンして決定することを推奨します。

##### NOTE
- A/Bテスト有意差 測定結果は勝ちパターンを選択すると下記のような表示になり、各パターンの比較結果が表示されないようになります



**結果の推移**

グラフにはイベント起点プッシュ通知の開封率、コンバージョン率がパターンごとに表示されています。



**一覧画面**

A/Bテストを実行しているキャンペーンが公開中または非公開の場合に、一覧画面で各キャンペーンのA/Bテストの状態を確認できます。
アイコンの表示条件は次のとおりです。

| アイコン | 表示条件 |
| --- | --- |
|  | 有意差があり、ベースラインを上回る結果のパターンが1つ以上存在する場合 |
|  | 有意差があり、ベースラインを下回る結果のパターンのみが存在する場合 |
|  | 有意差がないパターンのみが存在する場合 |
|  | 全てのパターンで計算ができない場合 |
|  | 勝ちパターンを選択済みの場合 |
|  | A/Bテストを実行していて、ベースラインとなるパターンか対象となる指標が設定されていない場合 |
| ー | キャンペーンがA/Bテストを実行していない場合 |

##### NOTE
- 有意差があり、ベースラインを上回る結果と下回る結果のキャンペーンが両方ともに存在する場合には、ベースラインを上回る結果が1つでも存在する場合として表示がされます
- ご不明点がある場合 [FAQ](https://docs.repro.io/ja/faq/general/index.md) もあわせてご確認ください

#### 勝ちパターンを選ぶ

勝ちパターンを選ぶと、以降のイベント起点プッシュ通知ではそのパターンがすべてのユーザーに配信されるようになります。

リテンションレートの向上を目的として作成したイベント起点プッシュ通知であれば開封率の高いパターンを、KPIの向上目的としているならば、コンバージョン率の高いパターンを選択するとよいでしょう。

### よくあるご質問

- イベント起点プッシュ通知の配信上限はありますか？
  - 配信数に上限はありません。公開可能キャンペーン数は増枠することが可能です。詳細は担当CSにご確認ください。
    : - ※ 通常のプッシュ通知とは別枠として管理されます。
- 効果はどのように計測するのですか？
  - 通常のプッシュ通知と同様の計測が可能です。
    : - ※ イベント起点プッシュではコントロールグループを使えません。

##### NOTE
1ユーザーに対し、プッシュ通知が配信可能なデバイストークンやRegistration IDのうち登録された日時が最新のものから1,000件のデバイスにのみプッシュ通知を配信します。
 
テスト用のユーザーなど、1ユーザーに対して大量のデバイストークンやRegistration IDが紐付いている場合、1,001件目以降のデバイスにはプッシュ通知が配信されなくなりますのでご注意ください。

---

## 閲覧人数表示

##### NOTE
- Webメッセージのみの機能提供になります。

閲覧人数表示は「この商品を1時間以内に100人が閲覧しています」などの、サイト上でコンバージョンするか迷っているエンドユーザーに対して、今を逃すと機会損失になることを意識させ、コンバージョンを促すのに効果的なメッセージを表示する機能です。

### 閲覧人数表示の仕組み

閲覧人数表示メッセージで利用する値（例:「1時間以内に100人が閲覧しています」の「100」の部分。これを「閲覧人数表示集計値」と呼びます）は
[イベントプロパティ](https://docs.repro.io/ja/dev/web/tracking.html) の発火回数の集計値を利用しています。例えば、閲覧イベントのurlプロパティを選んだ場合は、1時間で発生した閲覧イベントのurlプロパティごとのユニークユーザー数を計測します。

(具体例) イベントとしてセッション開始、集計対象イベントプロパティにurlを設定する場合を考えます。

当該のWebサイトのurlが https://www.example.com だったとします。このとき集計されるのは、https://www.example.com を訪れて、セッション開始のイベントを実行したユニークユーザー数を、1時間ごとのセッション開始のイベントのurlプロパティ（ユニークユーザーベース）で計測したものになります。

##### NOTE
- 全イベントに自動付与されているプロパティのうち url, path, query, title のみご利用いただけます。
- 各標準イベントで定義されているプロパティ、標準イベントの独自プロパティ、カスタムイベントの独自プロパティはご利用できません。



### 閲覧人数表示の使い方

#### 1.イベントの設定

サイト内で集計したいイベントプロパティ設定してください。

（例）イベント「PageView」のプロパティ設定

```javascript
reproio("track", "PageView");
```

詳しくは [イベントトラッキング](https://docs.repro.io/ja/dev/web/tracking.html) をご参照ください。

#### 2.閲覧人数表示キャンペーンの作成

##### 閲覧人数表示のテンプレート選択



マーケティング > メッセージ に行き、 新規作成ボタンから Webメッセージ をクリックしてください。

「閲覧人数表示」のテンプレートはそのほかの種類のメッセージテンプレートと組み合わせて使います。

例えば「ダイアログ」のタイプを元にした「閲覧人数表示」のテンプレートは「閲覧人数表示(ダイアログ)」のような表記がされているので、こちらを選択します。

##### キャンペーンを設定する

キャンペーン名やコンバージョンイベントの設定をします。
詳細は [キャンペーンを設定する](https://docs.repro.io/ja/dashboard/campaign/web-message.html#id3) をご覧ください。

##### 表示位置を設定する

組み合わされるテンプレートに応じて、表示位置の指定は変わります。

例えば閲覧人数表示(ダイアログ)のテンプレートであれば、ウィンドウまたはページ上に固定のオプションが選ばれます。

詳細は [表示位置](https://docs.repro.io/ja/dashboard/campaign/web-message.md#web-message-position) をご覧ください。

##### コンテンツを編集する

組み合わされるテンプレートに応じて、編集可能なコンテンツは異なります。

詳細は下記をご参照ください。

[ダイアログ](https://docs.repro.io/ja/dashboard/campaign/web-message.md#web-message-version-dialog)

[埋め込み](https://docs.repro.io/ja/dashboard/campaign/web-message.md#web-message-version-embedded)

[吹き出し](https://docs.repro.io/ja/dashboard/campaign/web-message.md#web-message-version-balloon)

##### 閲覧人数表示設定をする



**数値**

閲覧人数の数値の部分の大きさ/太さ/色を指定出来ます。

**数値の前にくるテキスト**

閲覧人数の数値の前に来るテキストを指定します。大きさ/太さ/色を指定出来ます。

例えば、「過去1時間で100名のお客様が商品を閲覧しました。」というのがテキスト全体だとすると、「過去1時間で」の部分に相当します。

**数値の前にくるテキスト**

閲覧人数の数値の後に来るテキストを指定します。大きさ/太さ/色を指定出来ます。

例えば、「過去1時間で100名のお客様が商品を閲覧しました。」というのがテキスト全体だとすると、「名のお客様が商品を閲覧しました。」の部分に相当します。

**閲覧人数全体のデザイン調節**

閲覧人数全体のテキストの配置と余白を指定出来ます。

**集計対象イベントプロパティを設定する**

集計対象イベントプロパティとは、閲覧人数表示集計値として利用するイベントプロパティです。
例えば、「 1時間以内に10人の閲覧がありました。」の「10」の数値部分に利用されます。
集計したいイベントプロパティを選択してください。

##### NOTE
- 指定するイベントは配信トリガーのイベントと一致させる必要がありますので、ご注意ください。

##### NOTE
閲覧人数表示のテンプレート内でカスタムメッセージを利用される場合は誤って data-repro--social-proof-value 属性を消去しないようにご注意ください。閲覧人数表示が正しく行われません。

**表示しきい値を設定する**

閲覧人数表示集計値が表示しきい値未満の場合、メッセージを表示しないようにします。
デフォルトで0が設定されます。（つまり、常にメッセージが表示されます。）

##### 「配信対象者を各パターンに振り分ける」以降の設定

「配信対象者を各パターンに振り分ける」、「配信設定」、「メッセージ表示トリガー」、「配信対象設定」、等の設定は
[配信対象者を各パターンに振り分ける](https://docs.repro.io/ja/dashboard/campaign/web-message.html#id17) 以降をご覧ください。

##### 「公開」設定する

キャンペーン内容の作成が完了しましたら、「公開」ボタンを押下します。

#### 3.閲覧人数表示メッセージの表示

登録したキャンペーンのメッセージが表示されていることを確認してください。
もし、表示されない場合は閲覧人数表示集計値が表示しきい値未満の可能性があります。
表示しきい値を「0」に設定し直して、メッセージ表示の確認を行ってください。

##### NOTE
- 閲覧人数表示メッセージの配信はキャンペーン公開後、配信期間中であっても、最大1時間要することがあります。

#### 閲覧人数表示の集計値の更新に関して

- 閲覧人数表示の集計値は、直近1時間の期間に対する集計が5分ごとに行われ、その都度集計結果が更新されます。

##### NOTE
- 閲覧人数表示メッセージの作成と同時に配信を開始した場合、メッセージの作成以前に集まっているデータは集計対象に含まれません。メッセージ作成後に集まったデータを集計し、集計結果が表示しきい値を超えたタイミングからメッセージが表示されます。
- 同じ集計対象イベントとプロパティの組み合わせで作成された配信中のキャンペーンが存在する場合は、新しく作成と配信を開始したメッセージであっても作成以前に集まっているデータが集計対象に含まれる場合があります。



#### コントロールグループへのパターンの設定の反映に関して

効果測定をより正確に行うために下記のようなパターンの設定の引き継ぎが行われますのでご注意ください。

- **パターン1** の内容 がコントロールグループにも反映されます。

例) パターン1に下記のような設定を行った場合、コントロールグループにも画像内の枠で囲まれている値が反映されます



#### 異なるしきい値の設定されたパターン間でABテストを行う場合について

閲覧人数表示のしきい値をABテストすると、しきい値に応じてメッセージを見るユーザー群の性質が変化することからCVR同士の比較によるキャンペーン評価が難しくなる場合があります。そのため弊社では必要な場合を除き **閲覧人数表示のしきい値は各パターンで共通の値をご利用いただく** ことを推奨しております。

何かご不明の点がございましたら、担当の弊社カスタマーサクセスメンバーまでご連絡ください。

---

## Webプッシュ通知

Webプッシュ通知とは、アプリでお馴染みのプッシュ通知をWebの世界でも実現する手段です。例えば、ある商品の詳細ページを閲覧して購入に至らなかった顧客に対して、Webプッシュ通知で後から訴求することが可能になります。

Webプッシュ通知は対応しているブラウザやそのバージョンに制限があります。またいくつかの事前準備が必要です。以下ではこれらの制限や実際に通知を送るまでの手順について説明します。

### 対応ブラウザ

|  | Chrome | Firefox | Safari | Edge |
| --- | --- | --- | --- | --- |
| Desktop | 52~ | ✕ | 16~ | ✕ |
| Android | 52~ | ✕ | ✕ | ✕ |
| iOS | 115~ | ✕ | 16.4~ | ✕ |

### 導入手順

[Webプッシュ通知](https://docs.repro.io/ja/dev/web/web-push-notification.md) を参照のうえ導入作業を実施してください。

### Webプッシュ通知の作成と配信

#### 1）新規作成画面へ遷移する

**マーケティング > Webプッシュ通知** を開き、新規作成ボタンをクリックしてください。



#### 2）キャンペーン名の設定



##### キャンペーン名

キャンペーンに任意の名前をつけてください。可能な限り、キャンペーンの内容を要約した名前を設定することを推奨しております。

##### キャンペーンのゴール

キャンペーンのゴールとなるイベントを設定可能です。Webプッシュ通知が表示されてから24時間以内にこれらのイベントを実施したユーザーの数が集計されます。

##### キャンペーンの狙いと実施後の結果

キャンペーン開始前にキャンペーンの意図や目的を記入したり、キャンペーン実施後に結果や気づきを追記して、施策の振り返りや次回施策に活用します。

#### 3）配信対象の設定



イベントやユーザープロフィール、既存ユーザーといったセグメンテーションフィルターをつかって、配信対象となるユーザーを指定できます。
各フィルターは **and** 、 **and not** 、 **or** を使って、最大5個まで組み合わせられます。

- **and**: 指定した条件を全て満たすユーザーが対象になります
- **and not**: 指定した条件にあてはまるユーザーが対象から除外されます
- **or**: 指定した複数の条件のどれかにあてはまるユーザーが対象になります

##### オーディエンスでフィルタリング

[オーディエンス](https://docs.repro.io/ja/dashboard/campaign/audience.md) で作成したセグメンテーションを利用することができます。

##### NOTE
- フィルターオーディエンス: 他のフィルタリング条件と組み合わせることはできません。
- インポートオーディエンス: 他のフィルタリング条件と組み合わせることができます。

##### イベントでフィルタリング

[イベント](https://docs.repro.io/ja/dev/sdk/tracking.md) を実行したユーザーをセグメンテーションすることができます。実行した期間や回数を指定することができます。

##### イベントプロパティでフィルタリング

[イベント](https://docs.repro.io/ja/dev/sdk/tracking.md) を実行したユーザーのうち、実行されたイベントに付帯するプロパティにもとづいてユーザーをセグメンテーションすることができます。プロパティの名前や値、実行した期間や回数を指定することができます。

##### ユーザープロフィールでフィルタリング

[ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md) に登録されている情報にもとづいてユーザーをセグメンテーションすることができます。SDKでプロフィールの型に数値を指定している場合、「以上、以下、より大きい、より小さい」などをつかって、値を比較する条件を指定できます。文字を指定している場合、「一致する、一致しない、含む」などをつかって、条件を指定できます。日付を指定している場合、「◯日前以前、◯日前〜▢日前、特定日以前」などをつかって、条件を指定できます。

日付の指定については、[サポートサイトのFAQ](https://support.repro.io/hc/ja/articles/23886462974489) に詳細な説明がありますので、こちらも参考にしてください。

##### 既存ユーザー

Webプッシュ通知の受信を許諾している全てのユーザーが対象になります。既存ユーザーを利用する場合は、 **その他の条件をフィルターに使うことができません** ので、ご注意ください。

#### 4）配信設定



どのタイミングでWebプッシュ通知を送るかを設定できます。毎週日曜日の18:00に送るといった繰り返し設定も可能です。

#### 5）メッセージの設定



##### プッシュ通知の形式

スタンダード（管理画面の入力フォームを利用する）とカスタムJSON（管理画面の入力フォームと同様の内容を、JSON形式で指定）がご利用いただけます。

##### タイトル

Webプッシュ通知のタイトルを指定してください。

##### メッセージ

Webプッシュ通知の本文を指定してください。

##### アイコン

Webプッシュ通知が表示される際に利用されるアイコンを指定してください。MacOS(Safari)ではアイコンが表示されません。iOSではこの設定は無視され、別途設定するmanifestファイルに従ってアイコンが表示されます。

##### 画像

Webプッシュ通知が表示される際に利用される画像を指定してください。iOSとMacOSでは画像が表示されません。

##### URL

Webプッシュ通知をクリックした際の遷移先を指定してください。

##### ボタンを追加

Webプッシュ通知にボタンを追加したい場合は、こちらから指定が可能です。

カスタムJSON形式で利用可能なペイロードの例:

```json
{
  "title": "Sample",
  "options": {
    "body": "新商品登場！この機会を見逃すな！",
    "icon": "/assets/icon.png",
    "image": "",
    "actions": [
      {
        "action": "archive",
        "title" : "GET"
      }
    ],
    "data": {}
  }
}
```

ペイロードの詳しいフォーマットについては下記をご参照ください。なおiOSとmacOSではボタンは表示されません。
[https://developer.mozilla.org/ja/docs/Web/API/notification/Notification](https://developer.mozilla.org/ja/docs/Web/API/notification/Notification)

#### 通知・ボタンをクリックしたときの挙動

##### NOTE
- URLを設定している場合
  - 設定されたURLを別タブで開きます。
  - すでに設定されたURLが開かれている場合はそのURLを開いているタブにフォーカスします。
- URLを設定していない場合
  - 通知を閉じます。

### プレビューで確認する

ここまでの作業でWebプッシュ通知の準備は完了です。最後にプレビュー機能を使って、実際にユーザーに届くWebプッシュ通知が意図した見た目・挙動になっているかを確認することを推奨しております。

#### プレビューの利用方法


- ① デバイスごとにどういった見た目になるかを確認することができます。
- ② 実際にご利用中の端末に通知を送ることで、挙動の確認ができます。上記の例の設定だと、下記ような通知が届きます。



##### WARNING
- macOSでは画像は表示されません。ご注意ください。



### 効果測定

開封数やコンバージョン数といったWebプッシュ通知の効果を確認できます。





#### 配信結果

##### 配信数

- 通知を配信したユーザー数です。
- **Webプッシュ通知許諾を拒否したユーザーは配信数に含まれません。**
- データの集計のタイミングの都合上、 **一時的に配信数 < 開封数** となる可能性がございます。

##### 開封数

- 通知を開封したユーザー数です。
- 直接開封 + みなし開封 のユニークユーザー数となります。

##### 直接開封数

- 通知をクリックしたユーザー数です。
- 「押下数 + ボタン１押下数 + ボタン２押下数」のユニークユーザー数です。

##### みなし開封数

- 実際に通知が表示されてから1時間以内にそのサイトを開いたユーザー数
- **みなし開封には、通知の押下数や通知のポタンのクリック数は含まれません。**

##### 押下数

- 通知を押下したユーザー数です。

##### ボタン１押下数

- 通知のボタン１を押下したユーザー数です。

##### ボタン２押下数

- 通知のボタン２を押下したユーザー数です。

##### コンバージョン

- 実際に通知が表示されてから1時間以内に作成画面で指定したゴールを達成したユーザー数を日次で集計し、合計した数です。

##### コンバージョン率

- コンバージョン数 / 配信数 です。

##### NOTE
- 押下数と開封数の違いについて
  - 開封数は直接開封 + みなし開封のユニークユーザー数であり、Webプッシュ通知全体がどの程度ユーザーにみられたかを表します。
  - 一方で押下数は直接開封の構成要素の一つであり、直接開封のうちどの程度のユーザーが通知をクリックしたかを表しているという違いがあります。

---

## アプリ内パラメーター

アプリ内パラメーターは、ユーザーにアプリを更新してもらわなくてもアプリの動作や外観を変えられる機能です。
管理画面上で設定された値をアプリがサーバーから受け取り、その値を利用することでアプリの動作や外観を変えることができます。すべてのユーザーに配信するデフォルトの値を配信したり、特定のセグメントにだけ別の値を配信しキャンペーンとして活用することも可能です。

### アプリ内パラメーターでできること

| 用途 | 詳細 |
| --- | --- |
| ユーザーにアプリの外観や動作の変更をすばやく適用する | 管理画面上で設定された値を更新すると、その変更はすぐにアプリに適用されます。たとえばアプリ内パラメーターを利用して背景色を制御する実装を行えば、管理画面から値を更新するだけで季節に応じて背景色を変えることが可能になります。 |
| 特定のセグメントに対してアプリをカスタマイズし、A/Bテストする | アプリ内パラメーターを使ってキャンペーンを実施し、A/Bテストとして異なる値を配信した結果を比較することができます。一部のユーザーにのみ変更を適用しA/Bテストした後に、一番結果の良かった設定をすべてのユーザーに対して適用する、といった活用方法も可能です。 |

##### WARNING
- アプリ内パラメーターを導入する際には、画面上で設定した値を利用するアプリ側の実装が必ず必要になります。実装が一度済めば、管理画面から設定を変更することでアプリに変更が適用されるようになります。

### アプリ内パラメーターの仕組み

アプリ内パラメーターは、パラメーターと呼ばれるキーと値の組み合わせをReproのサーバーが配信し、その配信された値をアプリ側で受け取って利用することでさまざまな用途に利用できます。たとえばアプリの背景色の制御に利用したい場合は、 `main_background_color` というキーに `white` という値を設定したパラメータを配信する、といった具合に設定を行います。各パラメーターを識別するキーの名前はアプリごとに自由に決められるので、アプリ側で利用する際に分かりやすい名前をつけてください。

あるキーに対して実際に適用される値を設定するには、次の4つの方法があります。

1. アプリ側で静的なデフォルト値を設定する
   - アプリをリリースする時点で固定のデフォルト値を設定します。アプリがはじめて起動した時や、端末がオフライン状態などReproのサーバーと通信してアプリ内パラメーターの値を取得することができない状況では、このデフォルト値が利用されます。
2. アプリ側で動的にデフォルト値を設定する
   - Repro SDKが用意している機能を利用して、アプリの動作中に動的にデフォルト値を設定します。
3. 管理画面上でデフォルト値を設定する
   - すべてのユーザーに配信したい値を管理画面上で設定します。この設定はアプリ内パラメーターの画面からいつでも変更可能で、変更を保存するとそれ以降にアプリが起動した際に値が適用されます。
4. 管理画面上でキャンペーンを作成する
   - 特定のセグメントに合致するユーザーだけを対象として配信したい値を管理画面上で設定します。この設定はアプリ内パラメーターの画面からいつでも変更可能で、変更を保存するとそれ以降にアプリが起動した際に値が適用されます。

#### 値の優先順位

上記に示した4つの方法により設定された値は、次の図に示す優先順位により最終的な値が決まり端末に適用されます。


1. そのユーザーを対象としたキャンペーンとして設定された値
   - あるユーザーが複数のキャンペーンの配信対象に属しており、そのどちらも重複するキーの値を上書きする場合は、更新時刻が新しいキャンペーンの方の値が利用されます
   - あるキャンペーンがコントロールグループを含むA/Bテストを実施しており、ユーザーがこのコントロールグループに割り当てられた場合は「指定されたパラメーターキーの値を上書きしない」という挙動になります
2. 管理画面から指定されたデフォルトの値
3. アプリ側で動的にセットされたデフォルト値
4. アプリ側で静的にセットされたデフォルト値

##### NOTE
- 通信を省略する用途でアプリが取得した値がキャッシュされることはなく、常に最新の値をサーバーから取得し適用します。管理画面上で設定を変更すると、アプリが次に起動したタイミングでReproのサーバーから最新の値を取得し直すため、再びアプリを起動したときにその値が適用されます。
- 通信が不安定な状況などでReproのサーバーから値の取得に失敗した際は、直前に保持していた値を利用します。

### アプリ内パラメーターの制約

アプリ内パラメーターはプラットフォーム上の審査を通すことなくアプリの外観や動作を変えることのできる機能ですが、次のような用途には利用しないようご注意ください。

- ユーザーの承認が必要なタイプのアップデートを行わないこと。信頼できないアプリであるとみなされ、場合によってはアプリがリジェクトされるなどのリスクがあります。
- セキュアなデータ・プライバシー保護の必要のあるデータを取得する用途に利用しないこと。
- プラットフォームの制限や規約を回避しようとしないこと。

##### WARNING
プラットフォーム上許可されていないこと・実現できない機能を実現する用途には利用出来ません。たとえばアプリのアイコンを動的に変える、などの機能はプラットフォーム側で制約されている場合があり、この制約自体はアプリ内パラメーターを利用しても回避することはできません。

### アプリ内パラメーターを作成する



#### デフォルトのパラメーターを作成する

ここではデフォルト値としてすべてのユーザーに同じ値を配信する方法を説明します。



まずはメニューから「設定 > アプリ内パラメーター設定」をクリックして設定画面を開き、「新規作成」ボタンをクリックします。



作成画面に遷移したら、配信したいパラメーターのキー名とデフォルト値を入力します。たとえばアプリの背景色を制御するパラメーターとして利用する場合は、 `background_color` や `main_background_color` というキー名で、デフォルト値には `white` や `#fff` といった内容を記入します。キー名はアプリ側でパラメーターを参照する際に利用する名前と同じになっている必要があるので注意してください。またここで設定したパラメーターの用途や注意点などをメモとして残しておくと後で見たときの混乱を避けられるので、あわせてメモも記入しておいてください。

必要な項目の記入が終わったら保存ボタンを押して、デフォルトのパラメーター作成を完了します。

##### NOTE
- パラメーターのキー名には英数字とアンダースコアのみが利用できます。
- キー名はパラメーターの用途やアプリ側での使い方が分かるように、分かりやすい名前をつけてください。
- パラメーターのデフォルト値を入力する際にJSONエディタを利用することができますが、JSONエディタを使って入力した内容であっても値は **文字列型** として配信されます。アプリ側で値を利用する際にはJSON文字列をパースした上で中のオブジェクトを取り出し利用してください。



#### キャンペーンを作成する



メニューから「マーケティング > アプリ内パラメーター」をクリックしてアプリ内パラメーターの一覧画面を開き、「新規作成」ボタンをクリックします。



作成画面に遷移したら、ここで作成するキャンペーンに名前をつけ、またキャンペーンのゴールとなるイベントを選択してください。



つづけてこのキャンペーンで上書きして配信したいパラメーターの設定を行います。

**キー**
: デフォルトの値が設定済みのパラメーターのキーが並ぶので、値を上書きしたいキーを選択してください。すでにデフォルト値が設定済みのパラメーターでなくとも、このキャンペーンで新規にパラメーターと上書きする値の組み合わせを設定し保存することも可能です。

**値**
: 選択されたキーのデフォルト値を上書きする、このキャンペーン固有の値を記入してください。このキャンペーンの配信対象となったユーザーにはここで指定された値が配信されます。
   
  - バイトサイズ
    - 最大: 10,000バイト

##### 配信対象者を各パターンに振り分ける



[配信対象を選択する](#remote-config-select-target) で設定した配信対象者をコントロールグループと、パターン1に振り分けます。
コントロールグループ(統制群)とは、 **パラメーターを上書きしない対象者** を指します。
このアプリ内パラメーターキャンペーンの効果を計測するために、 **パラメーターを上書きするユーザー** と **パラメーターを上書きしないユーザー** で効果を比較できます。
パターンを増やした状態での設定方法は、 [A/Bテスト](#remote-config-ab) をご覧ください。

例えば、配信条件を **既存ユーザー** とした場合に、コントロールグループを **20%** 、 パターン1を **80%** に設定すると、既存ユーザーの中からランダムで抽出された **約80%** のユーザーにはパラメーターがキャンペーン内で指定した値で上書きされ、残りの **約20%** のユーザーにはデフォルトの値が配信されます。

###### 割合を設定する

デフォルトではコントロールグループ **0%**、パターン1 **100%** となっているため、配信対象として指定されたユーザーに **100%** 上書きされたパラメーターの値が配信されます。
コントロールグループを利用しない場合は、設定を変更する必要はありません。
コントロールグループを利用する場合は、コントロールグループとパターン1で合計100%となるように割合を設定出来ます。

**均等に振り分ける** をクリックすると、コントロールグループとパターン1を **50%** ずつに均等に振り分けます。
**均等に振り分ける(コントロールグループなし)** をクリックすると、コントロールグループを **0%**、パターン1を **100%** に設定します。

##### NOTE
- コントロールグループは **0%** ~ **99%** まで設定出来ます。
- パターン1は **1%** ~ **100%** まで設定出来ます。
- 整数のみ設定出来ます。
- 振り分け設定は新規作成時のみ行うことが出来ます。
- 配信数の規模により、設定した割合と実際の配信数が乖離することがあります。



##### 配信設定

**配信期間**
: キャンペーンを配信する期間を設定してください。ここで設定した期間、作成したキャンペーンにもとづいて上書きされたパラメーターの値が配信されます。ユーザーは [ユーザーID](https://docs.repro.io/ja/dev/sdk/user-id.md) で区別されます。

**配信曜日**
: 配信曜日の指定が行えます。曜日を選択することで、該当曜日にパラメーターの値が配信されます。指定しない場合は全ての曜日で配信が行われます。

**配信時間帯**
: 配信時間帯の指定が行えます。時間帯を選択することで、該当時間帯にパラメーターの値が配信されます。指定しない場合は全ての時間帯で配信が行われます。





##### 配信対象を選択する



イベントやユーザープロフィール、既存ユーザーといったセグメンテーションフィルターをつかって、配信対象となるユーザーを指定できます。各フィルターは **and** 、 **and not** 、 **or** を使って、最大5個まで組み合わせられます。

- **and**: 指定した条件を全て満たすユーザーが対象になります
- **and not**: 指定した条件にあてはまるユーザーが対象から除外されます
- **or**: 指定した複数の条件のどれかにあてはまるユーザーが対象になります

例えば:

- 3日前にアプリを使用して、その後2日間アプリを使っていないユーザーへ配信する場合


- 性別が女性で直近3日以内にイベントAかイベントBのどちらかを実行したユーザーへ配信する場合



###### オーディエンスでフィルタリング

[オーディエンス](https://docs.repro.io/ja/dashboard/campaign/audience.md) で作成したセグメンテーションを利用することができます。

##### NOTE
- フィルターオーディエンス: 他のフィルタリング条件と組み合わせることはできません。
- インポートオーディエンス: 他のフィルタリング条件と組み合わせることができます。

###### イベントでフィルタリング

[イベント](https://docs.repro.io/ja/dev/sdk/tracking.md) を実行したユーザーをセグメンテーションすることができます。実行した期間や回数を指定することができます。

###### イベントプロパティでフィルタリング

[イベント](https://docs.repro.io/ja/dev/sdk/tracking.md) を実行したユーザーのうち、実行されたイベントに付帯するプロパティにもとづいてユーザーをセグメンテーションすることができます。プロパティの名前や値、実行した期間や回数を指定することができます。

###### ユーザープロフィールでフィルタリング

[ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md) に登録されている情報にもとづいてユーザーをセグメンテーションすることができます。SDKでプロフィールの型に数値を指定している場合、「以上、以下、より大きい、より小さい」などをつかって、値を比較する条件を指定できます。文字を指定している場合、「一致する、一致しない、含む」などをつかって、条件を指定できます。日付を指定している場合、「◯日前以前、◯日前〜▢日前、特定日以前」などをつかって、条件を指定できます。

日付の指定については、[サポートサイトのFAQ](https://support.repro.io/hc/ja/articles/23886462974489) に詳細な説明がありますので、こちらも参考にしてください。

###### 既存ユーザー

Reproに登録されたすべてのユーザーが対象となります。既存ユーザーから特定条件を満たすユーザーを除外する場合は、 **and not** でフィルターを追加してください。



###### 初回ユーザー

アプリを初めて起動したユーザーを対象に上書きされたパラメーターを配信します。

##### NOTE
- アプリをインストールしてから1週間以上経って初めてアプリを起動した場合は初回ユーザーとして判定されないのでご注意ください。



##### 公開、もしくは、非公開にする

公開もしくは非公開をクリックする前に、設定したキャンペーンの内容を注意深くチェックしてください。
キャンペーンを公開、非公開で登録後からキャンペーンのゴール、パラメーターのパターン が **変更できなくなります。**

確認後、キャンペーンを公開する準備が整っていれば、 **公開** を、そうでない場合は **非公開** をクリックしてください。



##### 効果測定

キャンペーンの効果を確認できます。





###### 配信結果

**配信数**
: このキャンペーンによって上書きされた値が配信されたユーザー数を日次で集計し、合計した数です。

**コンバージョン数**
: 配信から24時間以内に、作成画面で指定したゴールを達成したユーザーの数を日次で集計し、合計した数です。

**コンバージョン率**
: コンバージョン数 / 配信数 です。

**結果の推移**
: キャンペーン実施期間中の配信数、コンバージョン数を日次で集計した結果を表示しています。計測単位はユーザーです。

##### NOTE
- たとえば既存ユーザー向けのアプリ内パラメーターキャンペーンが2つあり、そのどちらもが同じパラメーターキーを1つだけ上書きしていたとします。この場合、あるユーザーに送られる値は常にどちらかのキャンペーンのもの（最終更新が新しい方）であり、どちらも既存ユーザー向けではあるものの、もう片方のキャンペーンの値は送られないことになります。このように、あるキャンペーンによって上書きされた値が最終的にユーザーに届くアプリ内パラメーターの値として1つもなかったとしても、個々のキャンペーンの配信対象者となっている限りは「そのアプリ内パラメーターキャンペーンが配信された」こととして計測が行われます。



#### A/Bテスト

配信対象に指定したユーザーに複数のパターンのパラメーターを均等に配信することで、どのような値を配信して利用すればコンバージョン率が向上するのかを検証することができる機能です。

最も効果の高かった値を勝ちパターンとして指定することができます。

##### メッセージ作成

上書きするパラメーターの値のパターンを2個以上作成することで、A/Bテストを行うことができます。


- 最大4パターンまで追加することができます。
- パターンの追加や削除は新規作成時のみ行うことができます。

##### 配信対象者を各パターンに振り分ける



パターンを2つ以上に設定した場合も、各パターンに配信対象者を振り分けられます。
コントロールグループを含む各パターンの合計が100%になるように設定します。

**均等に振り分ける** をクリックすると、コントロールグループと各パターンを均等に振り分けます。
**均等に振り分ける(コントロールグループなし)** をクリックすると、コントロールグループを **0%** に設定し、 **100%** を各パターンで均等に振り分けます。

##### NOTE
- コントロールグループは **0%** ~ **99%** まで設定出来ます。
- 各パターンは **1%** ~ **100%** まで設定出来ます。
- 整数のみ設定出来ます。
- 振り分け設定は新規作成時のみ行うことが出来ます。
- 配信数の規模により、設定した割合と実際の配信数が乖離することがあります。

---

## シナリオ

シナリオでは、ユーザーの異なる行動に合わせてコミュニケーションシナリオを設計し、管理・運用することが可能となります。
商品購入などのテーマと想定されるユーザーの行動に応じ、Webメッセージ、アプリ内メッセージ、プッシュ通知、メールの配信タイミングと内容を出し分けることができます。



Webとアプリを横断したシナリオ設計も可能で、カスタマージャーニーに応じたコミュニケーションが実現できます。

### シナリオをはじめる前に

シナリオを作成するには、「管理者」または「オペレーター」権限が必要です。
権限を変更する場合は、[メンバーの権限を変更する](https://reproio.zendesk.com/hc/ja/articles/900005688303-%E3%83%A1%E3%83%B3%E3%83%90%E3%83%BC%E3%81%AE%E6%A8%A9%E9%99%90%E3%82%92%E5%A4%89%E6%9B%B4%E3%81%99%E3%82%8B) を参照してください。

### シナリオを作成する

それではシナリオを作成します。
シナリオに名前を付けた後、シナリオビルダーを利用してシナリオの中の「ステップ」としてキャンペーンを配置していきます。

#### シナリオを新規作成する

サイドメニューから[マーケティング] > [シナリオ]を選択します。



シナリオ一覧ページから[新規作成]をクリックします。



シナリオ作成画面が表示されます。



| 項目 | 説明 |
| --- | --- |
| シナリオの名前 | シナリオの名前を記入します。255文字以内で入力してください。 |

「シナリオの名前」を入力して、[シナリオを作成して次へ]をクリックします。



シナリオが作成されます。



| 項目 | 説明 |
| --- | --- |
| シナリオのねらいと説明 | 作成したシナリオの狙いと説明を記入します。5000文字以内で入力してください。 |
| シナリオビルダー/配信結果切り替えタブ | **シナリオビルダー** 選択するとシナリオの作成ができます。 **配信結果** シナリオの配信結果を表示します。 |
| ステップの追加 | シナリオにステップを追加します。 |

これでシナリオが作成されました。次に、シナリオビルダーを利用してステップにキャンペーンを追加します。

#### ステップにキャンペーンを追加し、シナリオを組み立てる

次に、ステップにキャンペーンを追加し、シナリオを組み立てていきます。

##### シナリオを組み立てる

それではシナリオを組み立てます。

今回は初回メッセージでお気に入り登録を促し、その後条件により下記2つのキャンペーンのいずれかを配信する設定を行います。

- お気に入り登録した場合：プレイリスト作成を訴求するメッセージを送信
- お気に入り登録しなかった場合：お気に入り登録を際訴求するメッセージを送信

シナリオビルダーより[ステップの追加]をクリックします。



各種キャンペーンの候補が表示されるので、追加するキャンペーンを選択します。



| 項目 | 説明 |
| --- | --- |
| プッシュ通知の追加 | [プッシュ通知を作成する](https://docs.repro.io/ja/dashboard/campaign/push-notification.md) 画面に遷移します。 |
| イベント起点プッシュ通知の追加 | [イベント起点プッシュ通知を作成する](https://docs.repro.io/ja/dashboard/campaign/event-based-push-notification.md) 画面に遷移します。 |
| アプリ内メッセージの追加 | [アプリ内メッセージを作成する](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md) 画面に遷移します。 |
| Webメッセージの追加 | [Webメッセージを作成する](https://docs.repro.io/ja/dashboard/campaign/web-message.md) 画面に遷移します。 |
| 一斉配信メールの追加 | [一斉配信メールを作成する](https://docs.repro.io/ja/dashboard/campaign/mail/broadcast-mail.md) 画面に遷移します。 |
| トリガーメールの追加 | [トリガーメールを作成する](https://docs.repro.io/ja/dashboard/campaign/mail/trigger-mail.md) 画面に遷移します。 |

シナリオでは上記4つのキャンペーンが追加できます。

##### NOTE
各キャンペーンの作成方法については、それぞれの作成方法ドキュメントをご確認ください。

- [プッシュ通知を作成する](https://docs.repro.io/ja/dashboard/campaign/push-notification.md)
- [イベント起点プッシュ通知を作成する](https://docs.repro.io/ja/dashboard/campaign/event-based-push-notification.md)
- [アプリ内メッセージを作成する](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md)
- [Webメッセージを作成する](https://docs.repro.io/ja/dashboard/campaign/web-message.md)
- [一斉配信メールを作成する](https://docs.repro.io/ja/dashboard/campaign/mail/broadcast-mail.md)
- [トリガーメールを作成する](https://docs.repro.io/ja/dashboard/campaign/mail/trigger-mail.md)

キャンペーンをクリックすると、各キャンペーンの作成ページへと遷移します。今回は[アプリ内メッセージの追加]をクリックします。



テンプレートを選択します。



アプリ内メッセージ作成画面が表示されるので、必要な項目を入力しキャンペーンを公開します。



作成したキャンペーンがシナリオに追加されます。



キャンペーンは以下のように表示されます。



| 項目 | 説明 |
| --- | --- |
| タイトル | キャンペーンの名前が表示されます。 |
| キャンペーン | キャンペーンのタイプが表示されます。 (プッシュ通知/イベント起点プッシュ/アプリ内メッセージ/Webメッセージ/一斉配信メール/トリガーメール/LINE) |
| ステータス | キャンペーンのステータスが表示されます。 (非公開/公開/終了/下書き/アーカイブ) |
| 配信期間 | キャンペーンの配信期間が表示されます。 |
| 配信対象 | 指定されている配信対象条件がすべて表示されます。 |
| トリガー | トリガーのイベントと条件が表示されます。 |

同様に[ステップの追加]をクリックし、2つ目のキャンペーンをステップに追加します。



[アプリ内メッセージの追加]をクリックします。



必要な項目を入力しキャンペーンを公開します。



なお、2つ目以降のキャンペーン作成時には、配信対象のフィルターに 「一つ前のキャンペーンが表示された」が自動で追加されます。



今回はフィルターで「お気に入り登録があること」をand条件で追加します。

「配信対象設定」より[フィルターを追加]をクリックします。



フィルターに追加します。



公開/非公開/下書き をクリックするとステップが追加されます。

##### NOTE
ステップを追加するとき、親ステップのキャンペーンが以下の条件に合致すると、公開/非公開を選択してもキャンペーンは保存されず、ステップが追加されません。

- 親ステップのキャンペーンの配信期間が終了している
- 追加するステップのキャンペーンの配信期間が親ステップのキャンペーンが終了して30日を超える日付を指定している



これで、1つ目のキャンペーンを表示し、お気に入り登録したユーザーに対して2つ目のキャンペーンが表示できます。

##### NOTE
親ステップに対して、分岐するステップは並列で4つまで追加可能です。

最後に3つ目のステップとして、「1つ目のメッセージを表示したが、お気に入り登録をしなかった」ユーザーに表示するメッセージを設定します。

１つ目のステップの[ステップを追加]をクリックします。



##### NOTE
1つ目のステップから分岐を増やす場合、1つ目のステップの下部にある [ステップの追加] から 対象のキャンペーンをクリックします。

[アプリ内メッセージの追加]をクリックします。



必要な項目を入力しキャンペーンを公開します。

今回は２つ目のステップとは逆に、2つ目のメッセージの配信対象と同様のフィルターを and not 条件で追加します。



公開/非公開/下書き をクリックするとステップが追加されます。



これで1つ目のメッセージを表示後にお気に入り登録しなかったユーザーに対して、お気に入り登録を再度促すメッセージを表示できます。

以上でシナリオの完成です。

#### ステップを削除する

ステップを削除する場合、シナリオ画面の対象ステップのゴミ箱アイコンをクリックします。



ポップアップで確認メッセージが表示されます。[削除]をクリックするとステップが削除されます。



##### NOTE
- ステップを削除すると、ステップに紐づくキャンペーンはアーカイブされます
- 親ステップは削除できません

#### シナリオの公開/非公開について

シナリオ自体には公開/非公開というステータスは存在しません。
各ステップのキャンペーンの公開/非公開によってシナリオの配信も制御されます。

##### 例１：1つ目のステップが「公開」、２つ目のステップが「非公開」の場合



１つ目のステップのみ配信され、2つ目のステップは配信されません。

##### 例２：1つ目のステップが「非公開」、２つ目のステップが「公開」の場合



キャンペーンは1つも配信されません。

##### NOTE
シナリオを途中で止めたい場合、止めたいステップのキャンペーンを「非公開」にしてください。

#### ステップに利用される各キャンペーンの上限数について

シナリオ内で作成したメッセージなどのキャンペーンは、各キャンペーンの利用数にも反映されます。

キャンペーンの上限数は、各キャンペーンの一覧画面の上部で確認できます。

例えばメッセージの上限数を確認したい場合は、サイドメニューから[マーケティング] > [メッセージ]をクリックし、画面上部を確認してください。



### 配信結果を確認する

シナリオ画面より[配信結果]タブをクリックします。



キャンペーンの配信結果が表示されます。



配信結果の表示項目はキャンペーンによって変わります。
それぞれ説明します。

#### プッシュ通知



| 項目 | 説明 |
| --- | --- |
| タイトル | キャンペーンの名前が表示されます。 |
| キャンペーン | キャンペーンのタイプが表示されます。 (プッシュ通知/イベント起点プッシュ/アプリ内メッセージ/Webメッセージ/一斉配信メール/トリガーメール/LINE) |
| ステータス | キャンペーンのステータスが表示されます。 (非公開/公開/終了/下書き/アーカイブ) |
| 配信期間 | キャンペーンの配信期間が表示されます。 |
| 配信 | キャンペーンの配信数が表示されます。 |
| 直接開封数（率） | キャンペーンの直接開封数と割合が表示されます。 |
| CV | キャンペーンのCV数と割合が表示されます。 |

#### イベント起点プッシュ



| 項目 | 説明 |
| --- | --- |
| タイトル | キャンペーンの名前が表示されます。 |
| キャンペーン | キャンペーンのタイプが表示されます。 (プッシュ通知/イベント起点プッシュ/アプリ内メッセージ/Webメッセージ/一斉配信メール/トリガーメール/LINE) |
| ステータス | キャンペーンのステータスが表示されます。 (非公開/公開/終了/下書き/アーカイブ) |
| 配信期間 | キャンペーンの配信期間が表示されます。 |
| 配信 | キャンペーンの配信数が表示されます。 |
| 直接開封数（率） | キャンペーンの直接開封数と割合が表示されます。 |
| CV | キャンペーンのCV数と割合が表示されます。 |

#### アプリ内メッセージ



| 項目 | 説明 |
| --- | --- |
| タイトル | キャンペーンの名前が表示されます。 |
| キャンペーン | キャンペーンのタイプが表示されます。 (プッシュ通知/イベント起点プッシュ/アプリ内メッセージ/Webメッセージ/一斉配信メール/トリガーメール/LINE) |
| ステータス | キャンペーンのステータスが表示されます。 (非公開/公開/終了/下書き/アーカイブ) |
| 配信期間 | キャンペーンの配信期間が表示されます。 |
| インプレッション | キャンペーンのインプレッション数が表示されます。 |
| メインCV | キャンペーンのメインCV数と割合が表示されます。 |

#### Webメッセージ



| 項目 | 説明 |
| --- | --- |
| タイトル | キャンペーンの名前が表示されます。 |
| キャンペーン | キャンペーンのタイプが表示されます。 (プッシュ通知/イベント起点プッシュ/アプリ内メッセージ/Webメッセージ/一斉配信メール/トリガーメール/LINE) |
| ステータス | キャンペーンのステータスが表示されます。 (非公開/公開/終了/下書き/アーカイブ) |
| 配信期間 | キャンペーンの配信期間が表示されます。 |
| インプレッション | キャンペーンのインプレッション数が表示されます。 |
| メインCV | キャンペーンのメインCV数と割合が表示されます。 |
| サブCV | キャンペーンのサブCV数と割合が表示されます。 （サブCVが設定されている場合のみ表示されます） |

#### 一斉配信メール



| 項目 | 説明 |
| --- | --- |
| タイトル | キャンペーンの名前が表示されます。 |
| キャンペーン | キャンペーンのタイプが表示されます。 (プッシュ通知/イベント起点プッシュ/アプリ内メッセージ/Webメッセージ/一斉配信メール/トリガーメール/LINE) |
| ステータス | キャンペーンのステータスが表示されます。 (配信中/配信予約/停止中/終了/下書き/アーカイブ) |
| 配信期間 | キャンペーンの配信期間が表示されます。 |
| 配信完了数 | キャンペーンの配信完了数が表示されます。 |
| 開封数 | キャンペーンの開封数と割合が表示されます。 |
| CV | キャンペーンのCV数と割合が表示されます。 |

#### トリガーメール



| 項目 | 説明 |
| --- | --- |
| タイトル | キャンペーンの名前が表示されます。 |
| キャンペーン | キャンペーンのタイプが表示されます。 (プッシュ通知/イベント起点プッシュ/アプリ内メッセージ/Webメッセージ/一斉配信メール/トリガーメール/LINE) |
| ステータス | キャンペーンのステータスが表示されます。 (配信中/配信予約/停止中/終了/下書き/アーカイブ) |
| 配信期間 | キャンペーンの配信期間が表示されます。 |
| 配信完了数 | キャンペーンの配信完了数が表示されます。 |
| 開封数 | キャンペーンの開封数と割合が表示されます。 |
| CV | キャンペーンのCV数と割合が表示されます。 |

#### LINEメッセージ



| 項目 | 説明 |
| --- | --- |
| タイトル | キャンペーンの名前が表示されます。 |
| キャンペーン | キャンペーンのタイプが表示されます。 (プッシュ通知/イベント起点プッシュ/アプリ内メッセージ/Webメッセージ/一斉配信メール/トリガーメール/LINE) |
| ステータス | キャンペーンのステータスが表示されます。 (配信中/配信予約/停止中/終了/下書き/アーカイブ) |
| 配信期間 | キャンペーンの配信期間が表示されます。 |
| 配信完了数 | キャンペーンの配信完了数が表示されます。 |
| CV | キャンペーンのCV数と割合が表示されます。 |

### 配信条件と配信結果に関する注意事項

##### WARNING
- シナリオ内のキャンペーンでA/Bテストを実施した際、コントロールグループに該当し実際にメッセージを配信/表示していないユーザーも「配信した」、「表示された」ユーザーとして配信対象に含まれます。
- キャンペーンのゴール設定をしないと、CVは0になります。
- 「CVした」に該当する条件は各キャンペーンで異なり、以下の条件になります：
  - プッシュ通知: 配信後１時間以内
  - イベント起点プッシュ通知: 配信後１時間以内
  - アプリ内メッセージ: 表示後24時間以内
  - Webメッセージ: 表示後24時間以内
  - 一斉配信メール: 開封後24時間以内
  - トリガーメール: 開封後24時間以内
  - LINEメッセージ: 配信後24時間以内

### シナリオ一覧画面を確認する



シナリオ一覧画面では、作成されたシナリオの名前とステータスが確認できます。
また、下書き状態のシナリオの削除や、作成済みのシナリオのアーカイブができます。

| 項目 | 説明 |
| --- | --- |
| ステータス | ステータスを表示します。1つ目のステップのステータスが表示されます。 ステップが一つもない場合はステータスは表示されません。 |
| 名前 | シナリオの名前を表示します。クリックするとシナリオ詳細画面へ遷移します。 |

#### シナリオ名で検索

シナリオ名を入力すると部分一致で検索できます。
シナリオ内のキャンペーンを含めた検索をすることはできません。

#### ステータスによる絞り込み

ステータスを指定して、シナリオを絞り込みできます。
絞り込みたいステータスにチェックを入れて、「適用」ボタンをクリックすることで指定したステータスのみに絞り込み出来ます。

* 公開中
* 非公開
* 終了
* アーカイブ
* 下書き

#### シナリオのアーカイブと削除



各項目の右にある三点リーダー(⋮)ボタンをクリックするとシナリオのアーカイブ、削除ができます。

| アクション | 説明 |
| --- | --- |
| 削除 | シナリオのステップがない場合、または下書きのみの場合はシナリオを削除できます。 削除するとシナリオに紐づくすべての下書きは削除されます。 |
| アーカイブ | 公開、非公開、終了キャンペーンを含むシナリオをアーカイブできます。 アーカイブするとシナリオに紐づくすべてのキャンペーンはアーカイブ、下書きは削除されます。 |

##### WARNING
- 削除、アーカイブをしたシナリオは元に戻すことはできません。

---

## トリガーメール

トリガーメールはサービスを利用中のユーザーの行動をきっかけにして、メールを配信する機能です。
例えば、「商品カートに追加」後、購入完了せずに離脱したユーザーに対して、1時間後に購入完了を促すことができます。

### メールアドレスのインポート

配信前の事前準備として、メールを配信したいユーザーのメールアドレスをReproにインポートする必要があります。事前準備は [Reproへのメールアドレスの連携](https://docs.repro.io/ja/dev/mail/email-address-integration.md) を参照してください。

### トリガーメールを作成する

#### トリガーメールの作成画面に遷移

管理画面にログインし、サイドメニューから[マーケティング] > [メール] をクリックします。



メール一覧画面から、[新規作成] > [トリガーメール]をクリックします。



#### キャンペーン情報を入力

キャンペーンの名前とキャンペーンのゴール、キャンペーンの狙いと実施後の結果を入力します。 （キャンペーンのゴールとキャンペーンの狙いと実施後の結果は任意です）



#### 配信対象を入力

キャンペーンの配信対象を指定します。フィルターを利用して、配信対象となるユーザーを絞り込めます。
あわせて、配信に利用するチャネルを選択します。
選択したチャネルを購読しているユーザーにのみ配信されます。対象チャネルを一度も購読していないユーザーや、すでに購読解除しているユーザーには配信されません。

##### NOTE
配信対象に「カート追加を1回以上」を指定し、トリガー条件も「カート追加」を指定した場合、「カート追加」を1回実行した時点でメールが配信されます。2回実行時ではないので設定時にはご注意ください。
なお、セグメンテーションに時間がかかる場合、その限りではありません。



配信対象設定の詳細は [配信対象設定](https://docs.repro.io/ja/dashboard/campaign/push-notification.md#push-measurement-filter) を参照してください。

##### 購読解除しているユーザーにも配信する



「購読解除しているユーザーにも配信する」にチェックを入れると、配信可能なユーザーに加えて、選択したチャネルを購読解除しているユーザーにも配信できます。
配信可能ユーザーなどのユーザー種別詳細は [配信リスト整備](https://docs.repro.io/ja/dev/mail/email-address-management.md) を参照してください。

配信停止、バウンスユーザーは購読解除しているユーザーに含まれないため、チェックを入れていても配信が行われません。

##### NOTE
「購読解除しているユーザーにも配信する」を選択していても、対象チャネルの購読状態が一度も登録されていないユーザーには配信されません。

##### WARNING
購読解除済みのユーザーにもメールが配信できるため、特定電子メール法、個人情報保護法、その他関連法令を遵守した上で利用してください。

以下のようなサービス利用に際して必須の情報を配信するメールでの利用を想定しています。

- 重要なお知らせ（サービスの障害、規約変更など）

以下のような広告・販促を主目的とするメールを送信する場合は、チェックを入れないようにしてください。

- 商品・サービスの購入を促す内容
- キャンペーン、セール、クーポン等の案内
- 利用促進・再訪問を目的としたマーケティングメッセージ

送信内容が「広告または販促」に該当するかの最終的な判断および責任は、利用者に帰属します。

##### 対象ユーザー数と配信可能ユーザー数

対象ユーザー数はReproに登録されているユーザーの中で条件に合致しているユーザー数の概算です。
配信可能ユーザー数は対象ユーザーのうち、指定されたチャネルで配信可能なメールアドレスが設定されているユーザーの数です。メールアドレスが登録されていない、バウンスアドレスや該当チャネルでは購読解除されているなど、配信可能なメールアドレスが設定されていないユーザーは配信可能ユーザー数に入りません。

#### 配信設定を入力

キャンペーンの配信設定を入力します。

- トリガー条件を入力します。メールを配信する起点となるイベントやプロパティを指定することができます。
  - 最大5つまでのイベントをOR条件で指定できます。
  - プロフィールの変化をトリガー条件とすることはできません。
- 指定した起点イベントの実行後すぐに配信するか、一定時間経過後に配信するかを選択することができます。
  - ただし、すぐに配信する設定を行った場合も、サーバーの混雑状況により配信まで数分〜数十分かかる場合があります。
  - 経過時間は最短15分後から最大7日後まで指定できます。
- 配信期間を設定します。
  - キャンペーンの保存後、配信期間は変更できません。変更する場合は該当のキャンペーンを複製してください。
- 配信時間帯を設定します。夜中や早朝などの意図しない時間帯の配信を防ぐために、配信が可能な時間を設定することができます。
  - 設定した配信時間帯以外にトリガーメールのトリガー条件のイベントが実行された場合、次の配信時間帯になった時点でトリガーメールが配信されます。
- 次の配信時間帯を待っている間にキャンペーンの配信期間を過ぎてしまった場合にはトリガーメールは配信されません。
  - キャンペーンの保存後、配信時間帯は変更できません。変更する場合は該当のキャンペーンを複製してください。
- 意図しないユーザーへの配信を止めるために、配信をキャンセルするイベントを指定できます。
  - 配信直前やトリガー発火直後にキャンセルするイベントが発生した場合など、配信をキャンセルするイベントの実行タイミングによっては、そのまま配信されてしまう可能性があります。
- メールが1日に何度も配信されることを防ぐため、配信頻度を設定できます。
  - 1日に何度も実行される可能性があるイベントをトリガー条件として登録する場合、メールが大量に配信される場合があります。



#### 差出人設定を入力

メールの差出人の設定を行います。差出人アドレスのドメインはメールお申し込みの際にReproで対応します。詳細は [配信前準備の概要](https://docs.repro.io/ja/dev/mail/anti-spam.md) を参照ください。



| 差出人メールアドレス | メールの差出人メールアドレスに表示されます |
| --- | --- |
| 差出人名 | メールの差出人名に表示されます |
| 返信メールアドレス | メールを受け取ったユーザーから返信を受け取る場合、差出人メールアドレスとは別のメールアドレスで受け取りたい場合に記入してください。 返信用メールアドレスの設定がない場合は、差出人メールアドレスが返信先として設定されます |

#### コンテンツを入力

メールの件名や本文を入力し、プレビューで内容を確認できます。
作ったメールはテスト配信で実際の表示を確認することも可能です。

| 件名 | 記入した内容が、メールの件名に表示されます |
| --- | --- |
| プレヘッダー | メーラーの一覧画面に表示される本文の先頭行を、このフィールドで記入した内容に差し替えることができます |
| HTMLメール | メール用のHTML/CSSを画面操作で作成することができます |
| テキストメール | 記入した内容がテキストメールの本文に表示されます。なお、テキストメールだけでの配信はできません |
| テスト配信 | 記入したメールアドレスへメールを配信します。カンマ区切りで複数のメールアドレスに送信することができます |

##### スタンダード

画面操作で本文を作成することができます。見出し、画像、ボタンなどをドラッグアンドドロップで配置可能です。



##### カスタム

メール用のHTML/CSSを直接入力して本文を作成することができます。お持ちのHTML/CSSをこちらに貼り付けてください。



###### カスタムエディタでの画像追加

HTML内に画像を挿入したい場合、画像を追加したい箇所にカーソルを移動し `画像を追加` をクリックしてください



画像を選択すると、アップロードした画像が指定されたimg要素がカーソル位置に追加されます。
アップロードした画像が崩れる場合は必要に応じてCSSを編集してください。



##### 購読解除URLの挿入

Reproが提供する購読解除URLを利用できます。 `{{ unsubscribe_url }}` を本文中に記載すると、 `https://email.repro.io/unsubscribe/xxxxx` のような購読設定の変更に利用できるURLがメール本文に挿入されます。
メールを受け取ったユーザーがURLから購読解除を行った場合は、そのメールが配信されたチャネルの購読状態が解除されます。

##### テスト配信

入力した件名、プレヘッダー、本文の表示確認のために、任意のメールアドレスにテスト配信することができます。テスト配信を行うメールアドレスはカンマ区切りで複数指定可能です。



##### NOTE
テスト配信機能では、Liquidを活用したパーソナライズ機能はご利用いただけません。 `{{ user_profile['name'] }}` のようなLiquidを含むメールをテスト配信機能を使って配信した場合、Liquid構文がそのまま配信されます。パーソナライズ機能の動作確認は、キャンペーンを公開した上でテスター向けに配信を行ってください。

#### 下書きで保存、非公開、公開



| 下書きで保存 | 作成途中の場合、下書き保存できます |
| --- | --- |
| 非公開 | トリガーメールを非公開状態で保存します。 非公開状態の場合、配信設定のトリガーイベントをトラックしてもトリガーメールは配信されません |
| 公開 | トリガーメールが公開(配信中)となり、配信設定のトリガーイベントをトラックした時に、メールが配信されます |

### 効果測定

メールの開封数やコンバージョン数といった、メールの配信結果を確認できます。

確認できる項目と各項目の定義は一斉配信と同様です。 [一斉配信のドキュメント](https://docs.repro.io/ja/dashboard/campaign/mail/broadcast-mail.md) を参照ください。

### Liquidによるパーソナライズ機能

Liquidを活用すれば、トリガーメールでユーザープロフィールやトリガーイベントのプロパティを変数として差し込み、メッセージの内容をパーソナライズできます。
利用方法の詳細は [Liquidを活用したパーソナライズ](https://docs.repro.io/ja/dashboard/campaign/liquid-personalization.md) を参照してください。

### よくあるご質問

- 一斉配信メールとの機能仕様の違いはありますか？
  : - 配信設定のみが違います。配信対象設定、コンテンツの作成方法、効果測定結果、Liquidによるパーソナライズ機能の利用は一斉配信メールと同様です。

---

## メール

Reproでは任意のユーザーにメールを配信することが可能です。
指定したタイミングで一斉配信を行う一斉配信メールと、ユーザーの行動をきっかけにして配信を行うトリガーメールの2種類の機能があります。

* [一斉配信メール](https://docs.repro.io/ja/dashboard/campaign/mail/broadcast-mail.md)
  * [メールアドレスのインポート](https://docs.repro.io/ja/dashboard/campaign/mail/broadcast-mail.md#id2)
  * [一斉配信メールを作成する](https://docs.repro.io/ja/dashboard/campaign/mail/broadcast-mail.md#id3)
  * [効果測定](https://docs.repro.io/ja/dashboard/campaign/mail/broadcast-mail.md#id23)
  * [メール一覧画面](https://docs.repro.io/ja/dashboard/campaign/mail/broadcast-mail.md#id28)
  * [Liquidによるパーソナライズ機能](https://docs.repro.io/ja/dashboard/campaign/mail/broadcast-mail.md#liquid)
* [トリガーメール](https://docs.repro.io/ja/dashboard/campaign/mail/trigger-mail.md)
  * [メールアドレスのインポート](https://docs.repro.io/ja/dashboard/campaign/mail/trigger-mail.md#id2)
  * [トリガーメールを作成する](https://docs.repro.io/ja/dashboard/campaign/mail/trigger-mail.md#id3)
  * [効果測定](https://docs.repro.io/ja/dashboard/campaign/mail/trigger-mail.md#id17)
  * [Liquidによるパーソナライズ機能](https://docs.repro.io/ja/dashboard/campaign/mail/trigger-mail.md#liquid)
  * [よくあるご質問](https://docs.repro.io/ja/dashboard/campaign/mail/trigger-mail.md#id18)
* [登録されたメールアドレスの指定方法](https://docs.repro.io/ja/dashboard/campaign/mail/email-address-selection.md)
  * [事前準備](https://docs.repro.io/ja/dashboard/campaign/mail/email-address-selection.md#id2)
  * [メールアドレス登録後の挙動](https://docs.repro.io/ja/dashboard/campaign/mail/email-address-selection.md#email-address-status-and-flags)
  * [メールアドレスの指定方法](https://docs.repro.io/ja/dashboard/campaign/mail/email-address-selection.md#id4)
  * [特定のメールアドレスリストで配信したい場合](https://docs.repro.io/ja/dashboard/campaign/mail/email-address-selection.md#id6)

---

## 登録されたメールアドレスの指定方法

登録されたメールアドレスを、どのようにメール配信時に指定するかを説明します。

### 事前準備

メールを配信する前に、
[Reproへのメールアドレス連携方法](https://docs.repro.io/ja/dev/mail/email-address-integration.md)
を参考に、メールアドレスを登録しておきます。

まだの場合は、メールアドレスの登録だけではなく、バウンス・オプトアウト等の配信停止リストの情報を Repro に登録するため、
[配信リスト整備](https://docs.repro.io/ja/dev/mail/email-address-management.md)
まで完了させてください。



### メールアドレス登録後の挙動

アドレス帳のように、ユーザー情報（ユーザーID）に対してメールアドレスが記録されます。

登録されたメールアドレスは、それぞれ以下のような情報とともに保存されています。

| ステータス | 停止フラグ | 状態 |
| --- | --- | --- |
| 配信可能 | ― | すべてのメールを配信する |
| 配信不可 | 購読解除（Unsubscribe） | ユーザー意思により、マーケティングメールを配信してはいけない |
| 配信不可 | 配信停止（Stop） | どんなメールも配信しない |
| 配信不可 | バウンス（Bounce） | メールアドレス都合で配信できない |

自動的に、ステータスが **配信可能** のメールアドレスのみが選出され、配信されます。

配信オプションである
「**購読解除しているユーザーにも配信する**」
を選択した場合、停止フラグが **購読解除（Unsubscribe）のみ** のメールアドレスは配信されます。

停止フラグは複数種を設定することが可能です。
**購読解除（Unsubscribe）** とあわせて、
**配信停止（Stop）** や **バウンス（Bounce）**
が登録されている場合もあります。

メールアドレスの状態や登録有無が分からない場合は、
設定 > メール設定 > メールアドレス一覧から確認してください。
（管理者以上の権限が必要です）



### メールアドレスの指定方法

メールを配信する際は、**配信対象設定** で指定します。
メールアドレスを直接取り扱う必要はありません。



事前に登録されたメールアドレスが紐づく **ユーザー情報** をもとに、メール配信を行います。

#### 例：次の予約が「明日」のユーザーに毎日メールを配信する

ユーザープロフィールに「次の予約日」を登録しておくことで、
配信日起点で「明日」が登録されているユーザーの
**配信可能なメールアドレスのみ** が自動的に抽出されます。



どのように指定すればよいか分からない場合は、以下の サポートサイトFAQ も参考にしてください。

- [対象ユーザーの設定時、フィルターや And・And not・OR の使い方](https://support.repro.io/hc/ja/articles/27795256698393)

### 特定のメールアドレスリストで配信したい場合

特定のメールアドレスリストを用いて配信したい場合は、
**ユーザーIDを用いてリスト化** し、インポート形式のオーディエンスを利用できます。

- [ユーザーリストをインポートする](https://docs.repro.io/ja/dashboard/campaign/audience.md#user-list-upload)
- 参考：サポートサイト [オーディエンスをインポートで作成・更新する](https://support.repro.io/hc/ja/articles/900004738366)

---

## データエクスポート

* [イベントデータエクスポート](https://docs.repro.io/ja/dashboard/export/event-data-export.md)
  * [はじめに](https://docs.repro.io/ja/dashboard/export/event-data-export.md#id2)
  * [出力仕様](https://docs.repro.io/ja/dashboard/export/event-data-export.md#id3)
* [ユーザーIDエクスポート](https://docs.repro.io/ja/dashboard/export/userid-export.md)
  * [はじめに](https://docs.repro.io/ja/dashboard/export/userid-export.md#id1)
  * [出力仕様](https://docs.repro.io/ja/dashboard/export/userid-export.md#id2)

---

## イベントデータエクスポート

[トラッキングしたイベント](https://docs.repro.io/ja/dev/sdk/tracking.md) のローデータをCSV形式でAmazon S3へエクスポートできます。
エクスポートしたデータは、Treasure Data、Spin AppなどのDMPやDomo、TableauなどのBIツールへ取り込み、分析に活用することができます。

### はじめに

イベントデータエクスポートはオプション機能です。ご利用希望の方は、管理画面右下のチャットもしくは弊社の営業担当へお問い合わせください。

### 出力仕様

イベントデータエクスポートで出力するローデータは、当社が準備するAmazon S3上にCSVをgz圧縮したファイル形式で書き出されます。

詳細は下記のとおりです。

| 属性 | 説明 |
| --- | --- |
| S3 オブジェクトキー | `{project_id}/custom_event_histories/yyyymmddhh/ {project_id}_custom_event_history_{index}.{hash}.csv.gz` |
| 出力形式 | CSV 形式、gz 圧縮、ヘッダーなし |
| 文字コード | UTF-8 |
| 改行コード | LF |
| エスケープ文字 | ダブルクォート(") |
| アップロード頻度 | 1 時間毎 |
| アップロード対象 (全件/差分) | 差分 |
| 出力対象データが存在しない場合 | ファイルは生成されない |
| ファイルサイズ | イベント数に依存 |

##### NOTE
- 機能が有効になってからデータを出力することが可能です。それ以前のデータを出力することはできません。
- データの保存期間は30日となります。
- アクセス分析等の管理画面に表示される数値は、集計結果を素早く管理画面に表示するように、ユーザー同定等の処理を行った後の概算結果であるため、イベントデータエクスポートで出力されるローデータ上の集計値とはズレが生じる可能性があります。ユーザー同定の詳細に関しては [ユーザーの定義](https://docs.repro.io/ja/dashboard/misc/user-definition.md) をご確認ください。

#### CSVフォーマット

CSVはヘッダーなしで下記のような内容です。

```
2022-04-01T00:00:00.000Z,event-41,"{""campaign_id"":""abcdefg"",""product_id"":512,""product_category"":""female""}",user-1234,ios,xxxx-xxxx-xxxx-xxxx,""
2022-04-01T00:00:00.000Z,event-33,"{""campaign_id"":""hijklmn"",""product_id"":417,""product_category"":""kids""}",user-9876,ios,xxxx-xxxx-xxxx-xxxx,""
2022-04-01T00:00:00.000Z,App Launch,,user-5678,android,xxxx-xxxx-xxxx-xxxx,""
```

各カラムは以下の意味を持ちます。

| カラム | 説明 | 例 |
| --- | --- | --- |
| `tracked_at` | トラッキング時刻(utc) | `2022-04-01T00:00:00.000Z` |
| `name` | イベント名 | `tracking_event_name` |
| `properties` | イベントプロパティ | `"{""gender"":""female"",""logged in"":""no""}"` |
| `user_id` | [ユーザーID](https://docs.repro.io/ja/dev/sdk/user-id.md) | `userA` |
| `os` | OS | `ios` |
| `device_id` | [デバイスID (IDFV, ANDROID_ID)](https://docs.repro.io/ja/dev/sdk/device-id.md) | `0000AB12-ABCD-4321-89AB-A1B2C3D4E5F` |
| (廃止済み) | 空文字列 | `""` |

##### NOTE
- 2024/04/23 以降、7 列目の出力は廃止され、一律で空文字列が出力されるようになりました。

---

## ユーザーIDエクスポート

[オーディエンス](https://docs.repro.io/ja/dashboard/campaign/audience.md) 対象ユーザーのユーザーIDをCSV形式でエクスポートできます。エクスポートしたデータは、オフラインデータと情報を繋いでシームレスなコミュニケーションを行ったり、LINEやチャットツールなどにインポートして別チャネルでユーザーとのコミュニケーションが行えます。

### はじめに

ユーザーIDエクスポートはオプション機能です。ご利用希望の方は、管理画面右下のチャットもしくは弊社の営業担当へお問い合わせください。

### 出力仕様

ユーザーIDエクスポートはオーディエンス詳細画面から実行できます。

サイドメニューから[マーケティング] > [オーディエンス]をクリックします。



オーディエンス一覧画面より、エクスポートするオーディエンスを選択します。



オーディエンス詳細画面より「エクスポートの開始」ボタンをクリックします。



「エクスポートの開始」ボタンをクリックすると、処理中を示すインジケーターが表示されます。エクスポートが完了すると自動的にステータスと最終出力日時が更新されます。エクスポート完了後は、下部にCSVのダウンロードリンクが表示されるのでクリックするとCSVのダウンロードが可能です。



##### NOTE
- エクスポートを開始しステータスがエクスポート中の場合、「エクスポートの開始」ボタンは無効化され押せなくなります。ダウンロードリンクが表示されるまでお待ちください。
- オーディエンスに含まれるユーザー数の規模によって、管理画面上からCSVのエクスポートが可能になるまでの時間が異なります。目安は5~15分程度です。
- 出力されたCSVのダウンロードリンクは3日で消去され、ダウンロードできなくなります。再度ユーザーIDエクスポートを実行することで、ダウンロードが可能になります。
- ダウンロードリンクをクリックしてもダウンロードができない場合は、画面をリロードし直してください。
- 対象ユーザー数に関係なく出力されるCSVファイルは4つが固定です。将来的には4つではなくなる可能性があります。
- 1つのCSVファイルに出力されるユーザーIDの上限数はありません。
- オーディエンスの対象ユーザー数は、ユーザーIDが設定されていないユーザーも含むため、CSVの出力データの合算と一致しないことがあります。
- オーディエンスを新規作成、または編集直後にエクスポートすると、計算中のデータが出力されることがあり、出力したCSVが管理画面上に表示される対象ユーザー数と揃わないことがあります。新規作成、編集後はしばらく待ってからエクスポートを実行してください（※エクスポートするデータが揃うまで、1時間ほどかかることがあります。）

#### CSVフォーマット

CSVはヘッダーなしで下記のような内容です。出力される内容はユーザーIDのみです。

```
XXXXXXXXX0001
XXXXXXXXX0002
XXXXXXXXX0003
```

---

## イベント

* [イベント設定](https://docs.repro.io/ja/dashboard/event/event-settings.md)
  * [利用方法](https://docs.repro.io/ja/dashboard/event/event-settings.md#id3)
  * [イベント設定](https://docs.repro.io/ja/dashboard/event/event-settings.md#id4)

---

## イベント設定

イベント設定とは、Reproに登録されたイベントを管理する機能です。
イベントの利用可否の切り替え、管理画面上で扱うイベントの名称の変更、イベントの説明の追加ができます。
イベントについての詳細は「[イベント](https://support.repro.io/hc/ja/articles/19892893069721)」を確認してください。

### 利用方法

イベント設定は、Reproを導入したすべてのお客様が利用できます。
管理画面の左メニューより[イベント] > [イベント設定]にアクセスします。



### イベント設定

イベント設定画面で表示される各項目の定義と編集可能な項目を説明します。

#### 各項目の定義



| **項目名** | **説明** |
| --- | --- |
| イベント | アプリやWebでトラッキングしたイベントの名称です。 |
| 表示名 | 管理画面上で表示するイベントの名称です。 実装によりトラッキングした名称と別途で、各種アナリティクス機能やマーケティング機能を利用するときに表示する名称を設定できます。 |
| イベントの説明 | イベントの説明を詳細に入力できます。 概要やイベント発火するユーザーの定義、発火タイミング、備考や注意事項等を記載するとイベントの用途を把握しやすくなります。 |
| （On/Off） | イベントを利用するか選択します。 Onにしたイベントのみがデータポイントを消費してトラッキングされます。 Onにすると各種アナリティクス機能やマーケティング機能で利用できます。 |

#### 編集可能な項目

イベント設定で編集可能な項目は次の3つです。

1. 表示名
2. イベントの説明
3. On/Off

##### 表示名

表示名をイベントの用途に合わせてわかりやすい名称に編集することで、管理画面上でイベントを扱いやすくなります。

##### NOTE
[標準イベント](/ja/dev/sdk/tracking.html#standard-event) およびReproSDKがデフォルトで収集するイベントは表示名を変更できません。
デフォルトで取得するイベントのうち、イベント設定で表示されるイベントはReproAppでは「初回起動」、ReproWebでは「セッション開始」です。

##### イベントの説明

イベントの定義内容（概要、発火条件、対象ユーザー、発火タイミング、備考など）を明確に記載しておくことで、施策設計時やデータ分析時に「このイベントが何を表しているのか」「どのような意図で実装されたのか」を正確に理解できます。
 
また、メンバー間で共通認識を持つことができ、イベントの重複登録や誤用の防止にもつながります。
 

##### On/Off

イベントのOn/Offを切り替えることで、アプリやWebサイトの実装を変更することなく、イベントトラッキングを実行・停止できます。

##### NOTE
キャンペーンの配信対象の絞り込みに利用されているイベントを無効にすると、該当するキャンペーンは配信されなくなります。

編集した項目は画面下部の[保存]ボタンをクリックすると反映されます。



#### イベントの削除

イベントを削除することはできません。
不要になったイベントはOffにしてください。

#### イベントの利用数

画面右上に利用中のイベントの数が `[利用数/利用可能上限数]` で表示されます。



この例では利用可能上限数200件に対し、100件利用中であることが表示されています。
Onにしたイベントの数が利用数として計上されます。
利用数が利用可能上限数に達すると新しいイベントはトラッキングされず、Reproに登録されません。

##### NOTE
利用可能上限数を超えてイベントを利用したい場合は弊社のカスタマーサクセス担当、もしくはRepro管理画面の右下にあるアイコンよりチャットサポートへお問い合わせください。

---

## ユーザープロフィール

* [ユーザープロフィール設定](https://docs.repro.io/ja/dashboard/user-profile/user-profile-settings.md)
  * [利用方法](https://docs.repro.io/ja/dashboard/user-profile/user-profile-settings.md#id3)
  * [ユーザープロフィール設定](https://docs.repro.io/ja/dashboard/user-profile/user-profile-settings.md#id4)

---

## ユーザープロフィール設定

ユーザープロフィール設定とは、Reproに登録された [ユーザープロフィール](https://support.repro.io/hc/ja/articles/21591991285785) を管理する機能です。
過去に登録したユーザープロフィールの説明を追加したり、利用可否が切り替えられます。

### 利用方法

ユーザープロフィール設定は、Reproを導入したすべてのお客様が利用できます。
管理画面の左メニューより[ユーザープロフィール] > [ユーザープロフィール設定]にアクセスします。



### ユーザープロフィール設定

ユーザープロフィール設定画面で表示される各項目の定義と変更方法を説明します。

#### 各項目の定義



| **項目名** | **説明** |
| --- | --- |
| ユーザープロフィール | 登録されたユーザープロフィールの名称です。 |
| データ型 | 登録されたユーザープロフィールのデータ型です。 ユーザープロフィールのデータ型として指定可能な「文字列」/「整数」/「小数」/「日付」のいずれかが表示されます。 |
| ユーザープロフィールの説明 | ユーザープロフィールの説明を詳細に入力できます。 概要や更新タイミング、セットされるユーザーの定義、備考や注意事項等を記載するとユーザープロフィールの用途を把握しやすくなります。 |
| （On/Off） | ユーザープロフィールを利用するか選択します。 Onにするとアナリティクス機能やマーケティング機能で利用できます。 |

##### NOTE
ReproSDKがデフォルトで設定するユーザープロフィールもユーザープロフィール設定に表示されます。
ReproSDKがデフォルトで設定するユーザープロフィールは次の3つです。

- 最後に使った日
- ロケール
- タイムゾーン

#### ユーザープロフィールの変更

ユーザープロフィール設定画面で変更可能な項目は「ユーザープロフィールの説明」「On/Off」のみです。
ユーザープロフィール、データ型は変更できず、削除もできません。

編集した項目は画面下部の[保存]ボタンをクリックすると反映されます。



#### ユーザープロフィールの利用数

画面右上に利用中のユーザープロフィールの数が `[利用数/利用可能上限数]` で表示されます。



この例では利用可能上限数50件に対し、30件利用中であることが表示されています。
Onのユーザープロフィールを利用数として計上します。

新しく登録されたユーザープロフィールの状態は利用可能上限数に対して下記のようになります。

- 利用数が利用可能上限数未満の場合、新しく登録されたユーザープロフィールはOnの状態で表示されます。
- 利用数が利用可能上限数以上の場合、新しく登録されたユーザープロフィールはOffの状態で表示されます。

##### NOTE
利用可能上限数を超えてユーザープロフィールを利用したい場合は弊社のカスタマーサクセス担当、もしくはRepro管理画面の右下にあるアイコンよりチャットサポートへお問い合わせください。

---

## 設定

* [プロジェクト設定](https://docs.repro.io/ja/dashboard/setting/project-setting.md)
  * [Web SDKの設定](https://docs.repro.io/ja/dashboard/setting/project-setting.md#web-sdk)
* [Web設定](https://docs.repro.io/ja/dashboard/setting/web-tracking-rule.md)
  * [イベントトリガー](https://docs.repro.io/ja/dashboard/setting/web-tracking-rule.md#id1)
* [メンバー管理](https://docs.repro.io/ja/dashboard/setting/manage-members.md)
* [LINEチャネル設定](https://docs.repro.io/ja/dashboard/setting/line-channel-setting.md)
  * [LINEチャネルの新規作成](https://docs.repro.io/ja/dashboard/setting/line-channel-setting.md#id1)
  * [LINEチャネルの編集](https://docs.repro.io/ja/dashboard/setting/line-channel-setting.md#id2)
  * [LINEチャネルの削除](https://docs.repro.io/ja/dashboard/setting/line-channel-setting.md#id3)
* [ReproへのLINEユーザーIDの登録](https://docs.repro.io/ja/dashboard/setting/line-user-import.md)
  * [ReproへのLINEユーザーIDの登録方法](https://docs.repro.io/ja/dashboard/setting/line-user-import.md#id1)
  * [共通の準備事項](https://docs.repro.io/ja/dashboard/setting/line-user-import.md#id3)
  * [管理画面からインポートする](https://docs.repro.io/ja/dashboard/setting/line-user-import.md#id9)
  * [S3による自動インポート](https://docs.repro.io/ja/dashboard/setting/line-user-import.md#s3)
  * [Web/iOS/Android SDKを利用して登録](https://docs.repro.io/ja/dashboard/setting/line-user-import.md#web-ios-android-sdk)
* [セキュリティ設定](https://docs.repro.io/ja/dashboard/setting/security-setting.md)
  * [管理画面のIP制限](https://docs.repro.io/ja/dashboard/setting/security-setting.md#ip)
  * [ログインアクティビティ](https://docs.repro.io/ja/dashboard/setting/security-setting.md#login-activity)

---

## プロジェクト設定

### Web SDKの設定

[セットアップ計測タグを導入する](https://docs.repro.io/ja/dev/web/getstarted/web.md#install-setup-measurement-tags) で案内しているセットアップ計測タグのsetup オプション（ [reproio('setup', token, options)](https://docs.repro.io/ja/dev/web/api.md#api-setup) の options）を、管理画面から設定することができます。

セットアップ計測タグの変更を行うことなく、setup オプションを設定・変更できます。



##### NOTE
- WebSDKの設定で指定できるsetup オプションの項目は制限があります。
  - [クロスドメイン・トラッキング機能](https://docs.repro.io/ja/dev/web/cross-domain-tracking.md) や [WebViewでの動作](https://docs.repro.io/ja/dev/web/webview.md) を利用する場合はsetup APIのオプションを指定してください。

#### 設定方法

設定したいsetup オプションの項目に値を入力してください。

setup オプションの項目に値を入力した場合、セットアップ計測タグで設定した値を上書きします。入力しなかった場合は上書きされません。どちらも指定しなかった場合はシステム規定値が使われます。

setup オプションの詳細は [reproio('setup', token, options)](https://docs.repro.io/ja/dev/web/api.md#api-setup) を参照してください。

---

## メンバー管理

**設定 > メンバー管理** から管理画面へアクセスできるメンバーをメールアドレスで追加することができます。各メンバーには **管理者** 、 **オペレーター** のいずれかの権限を割り当ててください。権限によって、閲覧 / 編集できるページが異なります。

また、オーナーアカウントを変更したい場合は **プロジェクト設定 > 全般 > オーナーの変更** からプロジェクトのオーナーを変更してください。

| メニュー | 画面 | オーナー | 管理者 | オペレーター | 閲覧者 |
| --- | --- | --- | --- | --- | --- |
| ダッシュボード |  | <i class="fa fa-eye"></i> | <i class="fa fa-eye"></i> | <i class="fa fa-eye"></i> | <i class="fa fa-eye"></i> |
| アナリティクス | リテンション分析 | <i class="fa fa-eye"></i> | <i class="fa fa-eye"></i> | <i class="fa fa-eye"></i> | <i class="fa fa-eye"></i> |
| アナリティクス | アクセス分析 | <i class="fa fa-eye"></i> | <i class="fa fa-eye"></i> | <i class="fa fa-eye"></i> | <i class="fa fa-eye"></i> |
| アナリティクス | KPI分析 | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> |
| アナリティクス | ファネル分析 | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> |
| マーケティング | プッシュ通知 | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> |
| マーケティング | アプリ内メッセージ | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> |
| マーケティング | インセンティブコード管理 | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> |
| マーケティング | オーディエンス | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> |
| イベント | データエクスポート | <i class="fa fa-eye"></i> | <i class="fa fa-eye"></i> | <i class="fa fa-eye"></i> | <i class="fa fa-eye"></i> |
| イベント | イベント設定 | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> |  |  |
| ユーザープロフィール | データインポート | <i class="fa fa-eye"></i> | <i class="fa fa-eye"></i> | <i class="fa fa-eye"></i> |  |
| ユーザープロフィール | ユーザープロフィール設定 | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> |  |  |
| 設定 | プロジェクト設定 | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> |  |
| 設定 | プロジェクト設定 (プラン変更、オーナー変更、プロジェクトの削除) | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> |  |  |  |
| 設定 | Web設定 | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> |  |  |
| 設定 | プッシュ通知設定 | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> | <i class="fa fa-eye"></i> |
| 設定 | お支払い | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> |  |  |
| 設定 | メンバー管理 | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> | <i class="fa fa-eye"></i> |
| 設定 | セキュリティ設定 | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> |  |  |
| 設定 | メール通知 ON/OFF | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> |
| ヘルプ |  | <i class="fa fa-eye"></i> | <i class="fa fa-eye"></i> | <i class="fa fa-eye"></i> | <i class="fa fa-eye"></i> |
| アカウント |  | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> | <i class="fa fa-eye"></i> / <i class="fa fa-edit"></i> |

<i class="fa fa-eye"></i>: 閲覧可、 <i class="fa fa-edit"></i>: 編集可

---

## セキュリティ設定



### 管理画面のIP制限

Reproの管理画面への不正アクセスを防ぐため、設定 > セキュリティ設定 > 管理画面のIP制限 より管理画面にアクセス出来るIPアドレスを制限出来ます。

#### 設定方法



**1. 事前準備**

まずはシステム担当者の方に設定するIPアドレスをご確認ください。 以下のように固定IPアドレスが利用できない場合は本設定でIPアドレスを設定しても管理画面にアクセス出来なくなるのでご注意ください。

- オフィスで固定IPアドレスが導入されておらず、動的IPアドレスである
- リモートワークがメインでVPN等が利用できない

**2. IPアドレスを追加する**



「管理画面のアクセスを許可するIPアドレスを追加」からIPアドレスとそのIPアドレスに対する説明を任意で入力し追加ボタンをクリックするとIPアドレスが追加出来ます。
追加すると、アクセスを許可するIPアドレス、説明、設定したユーザーのメールアドレス、追加日時が一覧表示されます。

**3. 追加したIPアドレスを確認する**

追加したIPアドレスに間違いがないか確認します。 追加したIPアドレスに、アクセス元IPアドレスが含まれていない場合 **「あなたが現在アクセスしているIPアドレスが許可されていないためIPアドレス制限を有効にすることはできません。」** というメッセージが表示され、 **IPアドレス制限を有効にする** を `On` に出来ないのでご注意ください。

**4. IPアドレス制限を有効にする**



設定の確認が終わったら、設定画面上部の **IPアドレス制限を有効にする** の「Off/On」をクリックし、 `On` に変更し「保存」をクリックします。
画面がリロードされ、設定が有効になります。

**5. IPアドレス制限がかかっているか確認する**

許可したIPアドレス以外から管理画面にアクセス出来ないことを確認出来る環境があれば管理画面へアクセスを試み、設定が有効になっていることを確認します。

**許可するIPアドレスを削除する場合**



許可するIPアドレスを削除したい場合、右側にあるマイナスボタンから削除出来ます。 IPアドレス制限が有効になっている間はアクセス元のIPアドレスは削除できません。

##### NOTE
- 許可するIPアドレスは100件まで追加出来ます。
- ログインしている状態で、許可されていないIPアドレスから管理画面にアクセスした場合アカウント設定ページへリダイレクトされます。
- IPアドレスは [CIDR記法](https://ja.wikipedia.org/wiki/Classless_Inter-Domain_Routing) で設定することでまとめて指定することが出来ます。
- 管理画面へアクセスができなくなってしまった場合は、まずオーナーもしくは管理者権限のあるメンバーに相談し、必要に応じて許可するIPアドレスの設定を行ってください。
- オーナーもしくは管理者権限を持つメンバーが管理画面へアクセスできなくなってしまった場合は弊社CS担当、サポートへお問い合わせください。
- 各種APIへのアクセスはこの設定により制限されません。



### ログインアクティビティ

プロジェクトのメンバーがReproの管理画面のログイン、ログアウトする際のアクティビティログを取得できます。
通常とは異なる場所や端末からのログインや、アカウントに対しての不正なログイン試行を把握できます。

#### 取得期間


- 指定した期間のデータを取得できます。
- 現在から、最大で1年前までのデータを取得できます。
- 1年以上前のデータを取得したい場合は、サポートまでお問い合わせください。

##### NOTE
- 本機能リリース前である、2021年10月28日以前のデータは取得できません。

#### CSVフォーマット

```
Time (Tokyo+09:00),User email,Action type,Result,Additional information,IP address,User agent
"Oct 19, 2021 13:53:59",owner@example.com,Email/Password login,Succeed,,203.0.113.1,"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36"
"Oct 19, 2021 13:52:52",owner@example.com,Email/Password login,Failed,Incorrect password,203.0.113.1,"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36"
"Oct 19, 2021 13:52:42",owner@example.com,logout,Succeed,,203.0.113.1,"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36"
"Oct 19, 2021 13:52:38",owner@example.com,Email/Password login,Succeed,,203.0.113.1,"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36"
```

各カラムは以下の意味を持ちます。

| カラム | 説明 | 例 |
| --- | --- | --- |
| `Time` | アクティビティを記録した時刻、プロジェクトで設定したタイムゾーンで記録 | `"Oct 19, 2021 13:52:38"` |
| `User email` | メンバーのEメールアドレス | `"owner@example.com"` |
| `Action type` | ログインやログアウトなどのアクティビティの種類 | Eメール/パスワードでのログイン: `Email/Password login` ログアウト: `logout` アカウントのロック解除: `unlock` |
| `Result` | ログイン試行の成功/失敗 | 成功時: `Succeed` 失敗時: `Failed` |
| `Failed info` | ログイン試行失敗時の原因 | パスワードの間違い: `Incorrect password` アカウントロック: `Account locked` Eメールの確認が未完了: `Unconfirmed` |
| `IP address` | ログイン/ログアウトを試行した端末のIPアドレス | `203.0.113.1` |
| `User agent` | ログイン/ログアウトを試行した端末のユーザーエージェント | `"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36"` |

##### NOTE
- ログインアクティビティのダウンロードは、オーナーと管理者のみ可能です。

---

## アカウント

### アカウントロック

* [アカウントロック](https://docs.repro.io/ja/dashboard/account/account-lock.md)
  * [アカウントのロックを解除する](https://docs.repro.io/ja/dashboard/account/account-lock.md#id2)

### Googleログイン

* [Googleログインを設定する](https://docs.repro.io/ja/dashboard/account/link-to-google-account.md)
  * [Googleログインとは](https://docs.repro.io/ja/dashboard/account/link-to-google-account.md#id1)
  * [Googleアカウントで新規にReproのアカウントを作成する](https://docs.repro.io/ja/dashboard/account/link-to-google-account.md#googlerepro)
  * [招待されたメンバーがGoogleアカウントでReproのアカウントを作成する](https://docs.repro.io/ja/dashboard/account/link-to-google-account.md#id2)
  * [Googleアカウントを利用してログインする](https://docs.repro.io/ja/dashboard/account/link-to-google-account.md#id3)
  * [Googleアカウントとの連携を解除する](https://docs.repro.io/ja/dashboard/account/link-to-google-account.md#id4)
  * [Googleアカウントを連携する](https://docs.repro.io/ja/dashboard/account/link-to-google-account.md#id5)
  * [Google連携設定状況の確認](https://docs.repro.io/ja/dashboard/account/link-to-google-account.md#id6)
  * [FAQ](https://docs.repro.io/ja/dashboard/account/link-to-google-account.md#faq)

### 2要素認証

* [2要素認証を設定をする](https://docs.repro.io/ja/dashboard/account/two-factor-authentication.md)
  * [2要素認証とは](https://docs.repro.io/ja/dashboard/account/two-factor-authentication.md#id2)
  * [2要素認証を有効にする](https://docs.repro.io/ja/dashboard/account/two-factor-authentication.md#id3)
  * [2要素認証を利用してログインする](https://docs.repro.io/ja/dashboard/account/two-factor-authentication.md#id6)
  * [2要素認証を解除する](https://docs.repro.io/ja/dashboard/account/two-factor-authentication.md#id7)
  * [2要素認証設定状況の確認](https://docs.repro.io/ja/dashboard/account/two-factor-authentication.md#id8)
  * [FAQ](https://docs.repro.io/ja/dashboard/account/two-factor-authentication.md#faq)

### パスワード要件

Reproアカウントに設定するパスワードは、次の要件を満たす必要があります。

- 文字列長が12文字以上である
- 文字列長が72文字以下である
- 文字種が半角英数字、半角記号（スペースを含む）のみで構成される

##### NOTE
パスワードを設定するReproアカウントにて、使用するメールアドレスと同値で登録しようとするとエラーになります。
 
パスワード要件に則り、推測されにくい文字列を利用してください。
 

### ログイン状態保持期間

Repro管理画面では、ログイン後に操作されない期間が8日を超えると強制的にログアウトとなります。
その際、作業中の内容（入力や選択作業）はすべてリセットされますのでご注意ください。

---

## アカウントロック

不正ログイン防止のため、一定の時間内に規定回数のログインに失敗するとアカウントがロックされます。
アカウントがロックされると、ロックが解除されるまでログインすることができなくなります。

### アカウントのロックを解除する

アカウントのロックは以下の3通りの方法で解除できます。

- パスワードを忘れてしまった場合はパスワードを変更することで、アカウントのロックが解除されます。
- アカウントがロックされると、アカウントのメールアドレスにロックを解除するリンクが含まれたメールが送信されます。 メール内のリンクをクリックすることで、アカウントのロックが解除されます。
- 一定時間経過をすると、アカウントのロックが解除されます

##### NOTE
- アカウントのロックに心当たりがない場合は、弊社サポートまでお問い合わせください。

---

## Googleログインを設定する

### Googleログインとは

普段お使いのGoogleアカウントを使用してReproのアカウントを作成できたり、管理画面にログインすることができるようになります。
Googleログインが可能になることによって、下記の価値を提供します。

- 業務効率化
  - ReproアカウントとGoogleアカウントを連携することによって、普段お使いのGoogleアカウントを使用することができます。そのため、都度アカウント情報を入力する必要がありません。
- 認証情報の漏洩によるセキュリティリスク低下
  - サービス事業者（Repro）に認証情報を渡すことなく利用できるため、第三者がIDまたはパスワードを漏洩してしまった場合でも情報漏洩の影響を受けずに済みます。
  - 管理するID/パスワードがGoogleアカウントの1つとなるため、パスワードの使いまわしや漏洩のきっかけとなる脆弱なパスワード管理の防止にもつながります。

##### NOTE
- Googleアカウントのパスワード管理について

  Googleアカウントと連携済みの状態でGoogleアカウントの情報が漏洩した場合、そのGoogleアカウントを使用してRepro管理画面にも不正アクセスできる状態となります。
  Googleアカウントの不正アクセスを検知された場合、直ちにサポート担当者へお問い合わせください。

### Googleアカウントで新規にReproのアカウントを作成する

1. ログイン画面より、「アカウントを作成する」を押下してアカウント作成画面を表示します。

> 
1. アカウント作成画面より「Googleアカウントで登録」ボタンを押下します。このとき「サービス利用規約およびプライバシーポリシーに同意するチェックボックスにチェックをつけてください。

> 
1. ブラウザが複数のGoogleアカウントと連携している場合、Googleアカウントの選択画面が表示されます。Reproと連携設定しているGoogleアカウントを選択してください。

> 
1. 選択したGoogleアカウントが使用可能な場合、アカウント登録画面を表示します。プロジェクト名を入力し、「アカウント登録」ボタンを押してください。

> 

##### NOTE
選択したGoogleアカウントがすでに利用されている場合、そのGoogleアカウントを使用してアカウント登録を行うことはできません。お心当たりがない場合、サポート担当者までお問い合わせください。

### 招待されたメンバーがGoogleアカウントでReproのアカウントを作成する

1. はじめにRepro Webの利用申し込みをするとご連絡いただいたメールアドレスへ招待メールが届きます。 メール内の「招待を承認する」リンクをクリックし、アカウント登録画面を表示します。

> 
1. ブラウザが複数のGoogleアカウントと連携している場合、Googleアカウントの選択画面が表示されます。Reproと連携設定しているGoogleアカウントを選択してください。

> 
1. 選択したGoogleアカウントが使用可能な場合、アカウント登録画面を表示します。プロジェクト名を入力し、「アカウント登録」ボタンを押下してください。ダッシュボード画面に移動します。
2. 選択したGoogleアカウントがすでに利用されている場合、そのGoogleアカウントを使用してアカウント登録を行うことはできません。お心当たりがない場合、サポート担当者までお問い合わせください。

### Googleアカウントを利用してログインする

1. ログイン画面にて、「Googleアカウントでログイン」ボタンを押下します。

> 
1. ブラウザが複数のGoogleアカウントと連携している場合、Googleアカウントの選択画面が表示されます。Reproと連携設定しているGoogleアカウントを選択してください。

> 
1. 選択したGoogleアカウントと連携したReproアカウントが存在する場合、ダッシュボード画面に遷移します。
2. 選択したGoogleアカウントと連携したReproアカウントが存在しない場合、ログイン画面にエラーメッセージが表示され、ログインに失敗します。

### Googleアカウントとの連携を解除する

1. アカウント設定画面を開き、「連携を解除する」ボタンを押下します

> 

##### NOTE
GoogleアカウントからReproアカウントを作成した場合、Reproアカウントのパスワードが未設定の状態となっています。
パスワードが未設定の状態ではGoogle連携を解除することができません。
Google連携を解除する場合、アカウント設定画面からReproアカウントのパスワードの設定を行ってください。



### Googleアカウントを連携する

Emailアドレスで登録済みのReproアカウントとGoogleアカウントをあとから連携することも可能です。

1. アカウント設定画面を開き、「Googleアカウントと連携」ボタンを押下します。

> 
1. ブラウザが複数のGoogleアカウントと連携している場合、Googleアカウントの選択画面が表示されます。Reproと連携設定しているGoogleアカウントを選択してください。

> 
1. 選択したGoogleアカウントと連携が完了します。
2. エラーメッセージが表示されGoogleアカウントとの連携が完了しない場合、サポート担当までお問い合わせください。

##### NOTE
Reproアカウント作成後にGoogleアカウントと連携する場合、Repro管理画面には下記の2通りの方法でログインできる状態となっています。

- Reproアカウントのメールアドレス/パスワード
- Googleアカウント

Googleアカウントでのみログインを許可したい場合、プロジェクトのオーナー様より、Reproサポート担当までお問い合わせください。Reproアカウントのメールアドレス/パスワードによるログインができなくなるよう手続きを行います。

### Google連携設定状況の確認

メンバー管理画面より、Google連携の設定状況を確認できます。
Google連携を有効化しているユーザーには、セキュリティ列にアイコンが表示されます。



### FAQ

#### プロジェクトのメンバーにGoogleログインを強制することはできますか

現在、メンバーにGoogleログインを強制する機能は提供しておりません。
メンバーのGoogle連携の設定状況は、設定 ＞ メンバー管理画面からご確認いただくことができます。

#### Google以外のサービスでRepro管理画面にログインすることができますか

現在、Google以外のサービスでRepro管理画面にログインする機能は提供しておりません。

#### Googleアカウントでアカウントを作成しようとした際やReproアカウントとGoogleアカウントを連携しようとした場合、「選択したアカウントは既に利用されています」と表示されます

指定したGoogleアカウントがすでに他のReproアカウントと連携されている場合に表示されるメッセージです。お心当たりがない場合、サポート担当者までお問い合わせください。

---

## 2要素認証を設定をする

### 2要素認証とは

2要素認証とは、認証に使用する複数の情報のうち、本人確認のために2つの要素を組み合わせる認証方式です。
複数の認証要素を組み合わせることで、アカウントリスト攻撃や情報漏洩による不正アクセスのリスクを低減することができます。
Reproでは、認証に使用する3要素のうち「知識情報」「所持情報」の2要素を組み合わせた認証方法を設定可能です。

- 知識情報
  - パスワード、秘密の質問など
- 所持情報
  - 携帯電話、ハードウェアトークン、ICカードなど
- 生体情報
  - 指紋、静脈、声紋など

2要素認証を有効にするには、アカウント設定画面からお客様ご自身で設定していただく必要がございます。

### 2要素認証を有効にする

#### 認証アプリをダウンロードする

2要素認証を利用するために、認証アプリをスマートフォンにダウンロードする必要があります。
2要素認証設定画面に記載の内容を参考に、お持ちのスマートフォンに認証アプリをダウンロードしてください。

#### 管理画面にて2要素認証設定を行う

1. アカウント設定画面を開き、「2要素認証を設定する」 をクリックします。

> 
1. ダウンロードしたアプリよりQRコードを読み取ります。

##### NOTE
アプリによってQRコード読み取り方法は異なります。最新のアプリ仕様と下記記載の内容は異なる可能性があります。

* Google Authenticatorの場合

  画面右下にある「+」ボタンをタップし、「QRコードをスキャン」をタップしてQRコードを読み取ります。
* Authyの場合

  「Add Account」ボタンをタップし、「Scan QR Code」をタップしてQRコードを読み取ります。
* Microsoft Authenticatorの場合

  画面右上にある「+」ボタンをタップし、アカウントの種類から「その他」をタップしてQRコードを読み取ります。

1. カメラが起動するので、「STEP2 このQRコードをスキャンする」のQRコードを読み取ります。スキャン出来ない場合、2要素認証設定画面の「スキャン出来ない場合はこちら」をクリックして表示される内容に従って、キーを手動で入力してください。

> 
1. 認証アプリに表示された6桁のコードを確認します。
2. 6桁のコードを「STEP3 確認コードを入力」フィールドに入力し、「有効化」 をクリックして設定完了です。
3. 有効化後、画面にバックアップコードが表示されます。バックアップコードを安全な場所に保管してください。

##### NOTE
スマートフォンの紛失など、2要素認証に必要なデバイスをご利用いただけなくなってしまった場合、アカウントへログインできなくなります。
その際、2要素認証有効化時に発行されるバックアップコードを使用してログインすることが可能です。
バックアップコードは必ずコピーをとり、安全な場所に保管しておいてください。
バックアップコードはアカウント設定画面からいつでもご確認いただけます。
バックアップコードを紛失し、アカウントにログインできなくなった場合はサポート担当者へお問い合わせください。



1. 2要素認証を有効化すると、設定したアカウントのメールアドレス宛てに2要素認証有効化メールが送信されます。2要素認証設定を行っていないにもかかわらずメールを受信した場合、プロジェクト管理者へお問い合わせください。

### 2要素認証を利用してログインする

1. ログイン画面より、メールアドレス・パスワードでログインします。
2. 2要素認証コード入力画面が表示されるので、アプリを開き認証コードを確認し、コードを入力して「ログイン」をクリックします。

> 

### 2要素認証を解除する

1. アカウント設定画面 より、「2要素認証の設定を解除する」をクリックします。

> 
1. ポップアップ画面より、「2要素認証の設定を解除」 をクリックすると、2要素認証の設定が解除されます。

> 
1. 2要素認証を解除すると、設定したアカウントのメールアドレス宛てに2要素認証無効化メールが送信されます。2要素認証設定を行っていないにもかかわらずメールを受信した場合、プロジェクト管理者へお問い合わせください。

### 2要素認証設定状況の確認

メンバー管理画面より、2要素認証の設定状況を確認できます。
2要素認証を有効化しているユーザーには、セキュリティ列にアイコンが表示されます。



### FAQ

#### バックアップコードを使用して認証する場合

スマートフォンの紛失や、アプリにアクセスできずにコードが取得できない場合は、バックアップコードより認証が可能です。
バックアップコードは、アカウント設定画面の 「未使用のバックアップコード（10個）を確認する」からご確認いただけます。
なお、各バックアップコードは１度しか利用できません。コードを使い切った場合は、アカウント設定画面より「コードを再発行する」を押下して再発行手続きをしてください。
バックアップコードを紛失してしまったり、コードをすべて使い切ってしまったためにログインできない場合、お手数ですがサポート担当者までお問い合わせください。



#### スマートフォンを機種変更する場合

スマートフォンを機種変更する場合、認証アプリの移行作業が必要となります。
各アプリの移行手順につきましては、下記に記載の各アプリのドキュメントをご参考ください。

- Google Authenticator のコードを新しいスマートフォンに転送する
  - [https://support.google.com/accounts/answer/1066447?hl=ja](https://support.google.com/accounts/answer/1066447?hl=ja)
- 機種変更をするので Microsoft Authenticator のアカウントを移行したい
  - [https://support.microsoft.com/ja-jp/account-billing/%E3%82%A2%E3%83%97%E3%83%AA%E3%81%A7%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E8%B3%87%E6%A0%BC%E6%83%85%E5%A0%B1%E3%82%92%E3%83%90%E3%83%83%E3%82%AF%E3%82%A2%E3%83%83%E3%83%97%E3%81%8A%E3%82%88%E3%81%B3authenticator%E3%81%99%E3%82%8B-bb939936-7a8d-4e88-bc43-49bc1a700a40](https://support.microsoft.com/ja-jp/account-billing/%E3%82%A2%E3%83%97%E3%83%AA%E3%81%A7%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E8%B3%87%E6%A0%BC%E6%83%85%E5%A0%B1%E3%82%92%E3%83%90%E3%83%83%E3%82%AF%E3%82%A2%E3%83%83%E3%83%97%E3%81%8A%E3%82%88%E3%81%B3authenticator%E3%81%99%E3%82%8B-bb939936-7a8d-4e88-bc43-49bc1a700a40)
- 機種変更をするので Authy のアカウントを移行したい
  - [https://authy.com/blog/how-the-authy-two-factor-backups-work/](https://authy.com/blog/how-the-authy-two-factor-backups-work/)

#### スマートフォンを紛失、またはアプリを削除してしまった場合

スマートフォンを紛失、またはアプリを削除してしまった場合は、認証コードを取得することができません。そのため、下記いずれかの方法で対応をお願いします。

- バックアップコードを使用して認証する
- Reproサポート担当者に連絡し、2要素認証を解除する

  プロジェクトのオーナー様より、Reproサポート担当までお問い合わせください。2要素認証の解除手続きを行います。

#### プロジェクトメンバーの2要素認証を解除したい場合

プロジェクトメンバーの2要素認証を解除したい場合、管理画面右下のチャットよりReproサポート担当までお問い合わせください。メンバーの2要素認証の解除手続きを行います。



#### 2要素認証のコードを入力してもエラーが表示される場合

認証コード入力時に、アプリに表示されているコードを入力してもエラーが表示されログインできない場合、Reproサポート担当までお問い合わせください。

---

## その他

* [ユーザーの定義](https://docs.repro.io/ja/dashboard/misc/user-definition.md)
  * [新規ユーザー](https://docs.repro.io/ja/dashboard/misc/user-definition.md#id2)
  * [ユーザーとデバイスの関係（iOS/Android）](https://docs.repro.io/ja/dashboard/misc/user-definition.md#ios-android)
  * [ユーザーとブラウザの関係（Web）](https://docs.repro.io/ja/dashboard/misc/user-definition.md#web)
* [データポイント](https://docs.repro.io/ja/dashboard/misc/datapoints.md)
* [データの更新タイミング](https://docs.repro.io/ja/dashboard/misc/aggregation.md)
  * [アプリ内メッセージ・WEBメッセージ・アプリ内パラメーター](https://docs.repro.io/ja/dashboard/misc/aggregation.md#web)
  * [プッシュ通知](https://docs.repro.io/ja/dashboard/misc/aggregation.md#id2)
  * [アナリティクス](https://docs.repro.io/ja/dashboard/misc/aggregation.md#id3)
  * [マーケティング](https://docs.repro.io/ja/dashboard/misc/aggregation.md#id4)
* [データ保存期間](https://docs.repro.io/ja/dashboard/misc/data-retention-period.md)
* [CSVエクスポート](https://docs.repro.io/ja/dashboard/misc/csv-export.md)
  * [ダッシュボードの分析結果](https://docs.repro.io/ja/dashboard/misc/csv-export.md#id1)
  * [リテンション分析の結果](https://docs.repro.io/ja/dashboard/misc/csv-export.md#id2)
  * [アクセス分析の結果](https://docs.repro.io/ja/dashboard/misc/csv-export.md#id3)
  * [KPI分析の結果](https://docs.repro.io/ja/dashboard/misc/csv-export.md#kpi)
  * [ファネル分析の結果](https://docs.repro.io/ja/dashboard/misc/csv-export.md#id4)
  * [プッシュ通知の配信結果](https://docs.repro.io/ja/dashboard/misc/csv-export.md#id5)
  * [アプリ内メッセージの配信結果](https://docs.repro.io/ja/dashboard/misc/csv-export.md#id6)
  * [Webメッセージの配信結果](https://docs.repro.io/ja/dashboard/misc/csv-export.md#web)
  * [アプリ内パラメーターの配信結果](https://docs.repro.io/ja/dashboard/misc/csv-export.md#id7)
  * [イベント起点プッシュ通知の配信結果](https://docs.repro.io/ja/dashboard/misc/csv-export.md#id8)
  * [Webプッシュ通知の配信結果](https://docs.repro.io/ja/dashboard/misc/csv-export.md#id9)
* [メールの配信上限](https://docs.repro.io/ja/dashboard/misc/mail/sending-quota.md)
  * [1日の配信上限](https://docs.repro.io/ja/dashboard/misc/mail/sending-quota.md#id2)

---

## データポイント

Reproの各機能を利用すると、それぞれの機能やデータ量に応じてデータポイントを消費します。以下が各機能とデータポイント消費の対応表です。

- プロジェクトの現在のデータポイント消費量は **設定 > プロジェクト設定 > 全般** で確認できます。
- データポイントのリミットは毎月解除されます。

| カテゴリー | 機能 | データポイント |
| --- | --- | --- |
| **一般** | セッション | 1 データポイント / セッション |
| イベントトラッキング | 1 データポイント / トラック <sup>[1](#id7)</sup> |  |
| ユーザープロフィール | 1 データポイント / プロフィールの登録・更新 |  |
| **キャンペーン** | プッシュ通知の送信 | 1データポイント / デバイス |
| プッシュ通知の開封 | 1データポイント / 開封 <sup>[2](#id8)</sup> |  |
| アプリ内メッセージ表示 | 2データポイント / 表示 <sup>[3](#id9)</sup> |  |
| Webメッセージ表示 | 2データポイント / 表示 <sup>[4](#id10)</sup> |  |
* <a id='id7'>**[1]**</a> トラックとは、 [イベントトラッキング](https://docs.repro.io/ja/dev/sdk/tracking.md) のAPIをコールすることを指しています。
* <a id='id8'>**[2]**</a> このデータポイントはエンドユーザーが受信したプッシュ通知を実際に開いた時に加算されます。
* <a id='id9'>**[3]**</a> アクションボタン等のURLが開かれた際は追加で1データポイントが消費されます。
* <a id='id10'>**[4]**</a> メッセージの表示とボタン押下ごとに1ポイントずつ消費します。

データポイントが上限に達した場合、ご利用プランによって挙動が異なります。

Freeプランの場合はデータポイントが必要な全機能が停止しますが、Freeプラン以外の場合は即座に全機能停止することはありません。

Freeプラン以外のプロジェクトがデータポイント上限に達した場合、機能は以下の通り利用を制限されます。

**利用を制限される機能**
- マーケティング機能

**継続して利用できる機能**
- データ収集
- アナリティクス機能

データポイント上限到達後もデータポイント追加などをせずに継続利用をされていた場合、こちらからデータポイントを必要とする機能を停止する場合がございます。
データポイントを必要とする機能を停止した場合であっても、アプリやWebサイトの動作そのものに影響はありません。

データポイント追加を希望される場合は、管理画面右下のチャットもしくは弊社の営業担当へお問い合わせください。

---

## データ保存期間

ユーザーおよびユーザープロフィールは、Reproにおいて活用に適さないと判断したものを除き、Reproのサーバーへ最後にデータが送信されてから24ヶ月間のデータ保存を保証します。

---

## CSVエクスポート

ダッシュボードやアナリティクスの分析結果、キャンペーンの配信結果はCSV形式で出力することができます。

##### NOTE
- 管理画面のグラフにパーセント（％）で表示されている数値は小数で出力されます（例：30% -> 0.3）

### ダッシュボードの分析結果

ダッシュボードでは、それぞれの分析グラフ右上にある矢印ボタンをクリックすると、下記のデータを出力できます。

- アクティブユーザー数
- リテンション率

**CSVファイルのカラム定義**

- `日付`: 集計日（週次/月次のデータは集計期間の初日の日付）
- `全ユーザー`: 全ユーザーを対象とした数値
- `新規ユーザー`: 新規ユーザーを対象とした数値

##### NOTE
出力されるデータの期間は下記の通りです。
: - 日次: 集計が完了している日から過去14日間分
  - 週次: 集計が完了している週から過去8週間分
  - 月次: 集計が完了している月から過去12ヶ月間分

### リテンション分析の結果

リテンション分析では、分析結果画面の右上にある矢印ボタンをクリックすると、下記のデータを単位期間(日次/週次/月次)毎にCSVファイルへ出力できます。

**CSVファイルのカラム定義**

- `日付`: 再訪率を計算する際の起点となる日付
- `経過期間`: `日付` からの経過期間
- `再訪率`: `日付` から `経過期間` 後の再訪率
- `ユーザー数`: 再訪したユーザー数

### アクセス分析の結果

アクセス分析では、分析結果画面の右上にある矢印ボタンをクリックすると、下記のデータを単位期間(日次/週次/月次)毎にCSVファイルへ出力できます。この際 **設定 > イベント設定** で有効になっている全てのイベントが出力されます。

**CSVファイルのカラム定義**

- `日付`: 集計日（週次/月次のデータは集計期間の初日の日付）
- `イベント名`: 集計対象のイベント名
- `数値`: `イベント名` を実行した対象数(全ユーザー/新規ユーザー/全アクセス)

### KPI分析の結果

KPI分析では、分析結果画面の右上にある矢印ボタンをクリックすると、下記のデータを単位期間(日次/週次/月次)毎にCSVファイルへ出力できます。

**CSVファイルのカラム定義**

- `日付`: 集計日（週次/月次のデータは集計期間の初日の日付）
- `イベント名(回数)`: `イベント名(回数)` を達成したユーザー数

### ファネル分析の結果

ファネル分析では、分析結果画面の右上にある矢印ボタンをクリックすると、下記のデータを単位期間(日次/週次/月次)毎にCSVファイルへ出力できます。

**CSVファイルのカラム定義**

- `日付`: 集計日（週次/月次のデータは集計期間の初日の日付）
- `イベント名`: `イベント名` を達成したユーザー数

### プッシュ通知の配信結果

プッシュ通知配信結果では、画面右上にある矢印ボタンをクリックすると、下記のデータを出力できます。A/Bテストを利用した場合は、CSVファイルにプッシュ通知のパターン番号を示す `パターン` というカラムが追加されます。
CSVファイルにはプッシュ通知配信開始日から、効果測定の集計が完了している時点までのデータが出力されます。

カラム定義のうち、プッシュ通知の配信結果にも含まれるカラム定義の詳細は、[配信結果](https://docs.repro.io/ja/dashboard/campaign/push-notification.md#push-measurement-result) もご覧ください。

**CSVファイルのカラム定義**

- `パターン`: パターン(A/Bテストのみ)
- `日付`: 集計日
- `配信数`: 配信対象のユーザー数
- `開封数`: 通知を開封したユーザー数
- `直接開封数`: 直接開封したユーザー数
- `みなし開封数`: みなし開封したユーザー数
- `開封率`: 配信したユーザー数のうち、開封したユーザーの割合
- `コンバージョン数`: プッシュ通知の [開封](https://docs.repro.io/ja/dashboard/campaign/push-notification.md#push-measurement-result) 後、1時間以内にゴールに設定したイベントを実行したユーザー数（キャンペーンのゴール設定時のみ）
- `コンバージョン率`: コンバージョン数 / 配信数（キャンペーンのゴール設定時のみ）

### アプリ内メッセージの配信結果

アプリ内メッセージ配信結果では、画面右上にある矢印ボタンをクリックすると、下記のデータを出力できます。A/Bテストを利用した場合は、CSVファイルにアプリ内メッセージのパターン番号を示す `パターン` というカラムが追加されます。
CSVファイルにはアプリ内メッセージ配信開始日から、効果測定の集計が完了している時点までのデータが出力されます。

カラム定義のうち、アプリ内メッセージの配信結果にも含まれるカラム定義の詳細は、[配信結果](https://docs.repro.io/ja/dashboard/campaign/in-app-message.md#inapp-measurement-result) もご覧ください。

**CSVファイルのカラム定義**

- `パターン`: パターン(A/Bテストのみ)
- `日付`: 集計日
- `ユニークユーザー数-インプレッション`: メッセージを表示したユニークユーザー数
- `ユニークユーザー数-ボタン1押下数`: ボタン1を押下したユニークユーザー数（ボタン1設定時のみ）
- `ユニークユーザー数-ボタン2押下数`: ボタン2を押下したユニークユーザー数（ボタン2設定時のみ）
- `ユニークユーザー数-コンバージョン数`: 24時間以内にコンバージョンとして設定したイベントを実行したユニークユーザー数（キャンペーンのゴール設定時のみ）
- `ユニークユーザー数-コンバージョン率`: ユニークユーザーのコンバージョン数 / ユニークユーザーのインプレッション数（キャンペーンのゴール設定時のみ）
- `総回数-インプレッション`: メッセージが表示された総回数
- `総回数-ボタン1押下数`: ボタン1が押下された総回数（ボタン1設定時のみ）
- `総回数-ボタン2押下数`: ボタン2が押下された総回数（ボタン2設定時のみ）
- `総回数-コンバージョン数`: 24時間以内にコンバージョンとして設定したイベントが実行された総回数（キャンペーンのゴール設定時のみ）
- `総回数-コンバージョン率`: 総コンバージョン数 / 総インプレッション数（キャンペーンのゴール設定時のみ）

### Webメッセージの配信結果

Webメッセージ配信結果では、画面右上にある矢印ボタンをクリックすると、下記のデータを出力できます。A/Bテストを利用した場合は、CSVファイルにWebメッセージのパターン番号を示す `パターン` というカラムが追加されます。
CSVファイルにはWebメッセージ配信開始日から、効果測定の集計が完了している時点までのデータが出力されます。

カラム定義のうち、Webメッセージの配信結果にも含まれるカラム定義の詳細は、[配信結果](https://docs.repro.io/ja/dashboard/campaign/web-message.md#web-measurement-result) もご覧ください。

**CSVファイルのカラム定義**

- `パターン`: パターン(A/Bテストのみ)
- `日付`: 集計日
- `ユニークユーザー数-インプレッション`: メッセージを表示したユニークユーザー数
- `ユニークユーザー数-ボタン1押下数`: ボタン1をクリックしたユニークユーザー数（ボタン1設定時のみ）
- `ユニークユーザー数-ボタン2押下数`: ボタン2をクリックしたユニークユーザー数（ボタン2設定時のみ）
- `ユニークユーザー数-ボタン3押下数`: ボタン3をクリックしたユニークユーザー数（ボタン3設定時のみ）
- `ユニークユーザー数-ボタン4押下数`: ボタン4をクリックしたユニークユーザー数（ボタン4設定時のみ）
- `ユニークユーザー数-画像1押下数`: 画像1をクリックしたユニークユーザー数（画像1設定時のみ）
- `ユニークユーザー数-画像2押下数`: 画像2をクリックしたユニークユーザー数（画像2設定時のみ）
- `ユニークユーザー数-画像3押下数`: 画像3をクリックしたユニークユーザー数（画像3設定時のみ）
- `ユニークユーザー数-画像4押下数`: 画像4をクリックしたユニークユーザー数（画像4設定時のみ）
- `ユニークユーザー数-メインコンバージョン数`: 24時間以内にメインコンバージョンとして設定したイベントを実行したユニークユーザー数（キャンペーンのメインコンバージョン設定時のみ）
- `ユニークユーザー数-メインコンバージョン率`: ユニークユーザーのメインコンバージョン数 / ユニークユーザーのインプレッション数（キャンペーンのメインコンバージョン設定時のみ）
- `ユニークユーザー数-サブコンバージョン数`: 24時間以内にサブコンバージョンとして設定したイベントを実行したユニークユーザー数（キャンペーンのサブコンバージョン設定時のみ）
- `ユニークユーザー数-サブコンバージョン率`: ユニークユーザーのサブコンバージョン数 / ユニークユーザーのインプレッション数（キャンペーンのサブコンバージョン設定時のみ）
- `総回数-インプレッション`: メッセージが表示された総回数
- `総回数-ボタン1押下数`: ボタン1がクリックされた総回数（ボタン1設定時のみ）
- `総回数-ボタン2押下数`: ボタン2がクリックされた総回数（ボタン2設定時のみ）
- `総回数-ボタン3押下数`: ボタン3がクリックされた総回数（ボタン3設定時のみ）
- `総回数-ボタン4押下数`: ボタン4がクリックされた総回数（ボタン4設定時のみ）
- `総回数-画像1押下数`: 画像1がクリックされた総回数（画像1設定時のみ）
- `総回数-画像2押下数`: 画像2がクリックされた総回数（画像2設定時のみ）
- `総回数-画像3押下数`: 画像3がクリックされた総回数（画像3設定時のみ）
- `総回数-画像4押下数`: 画像4がクリックされた総回数（画像4設定時のみ）
- `総回数-メインコンバージョン数`: 24時間以内にメインコンバージョンとして設定したイベントが実行された総回数（キャンペーンのメインコンバージョン設定時のみ）
- `総回数-メインコンバージョン率`: 総メインコンバージョン数 / 総インプレッション数（キャンペーンのメインコンバージョン設定時のみ）
- `総回数-サブコンバージョン数`: 24時間以内にサブコンバージョンとして設定したイベントが実行された総回数（キャンペーンのサブコンバージョン設定時のみ）
- `総回数-サブコンバージョン率`: 総サブコンバージョン数 / 総インプレッション数（キャンペーンのサブコンバージョン設定時のみ）

### アプリ内パラメーターの配信結果

アプリ内パラメーター配信結果では、画面右上にある矢印ボタンをクリックすると、下記のデータを出力できます。A/Bテストを利用した場合は、CSVファイルにアプリ内パラメーターのパターン番号を示す `パターン` というカラムが追加されます。
CSVファイルにはアプリ内パラメーター配信開始日から、効果測定の集計が完了している時点までのデータが出力されます。

カラム定義のうち、アプリ内パラメーターの配信結果にも含まれるカラム定義の詳細は、[配信結果](https://docs.repro.io/ja/dashboard/campaign/remote-config.md#remote-config-measurement-result) もご覧ください。

**CSVファイルのカラム定義**

- `パターン`: パターン(A/Bテストのみ)
- `日付`: 集計日
- `ユニークユーザー数-インプレッション`: 配信したユニークユーザー数
- `ユニークユーザー数-コンバージョン数`: 24時間以内にコンバージョンとして設定したイベントを実行したユニークユーザー数（キャンペーンのゴール設定時のみ）
- `ユニークユーザー数-コンバージョン率`: ユニークユーザーのコンバージョン数 / ユニークユーザーのインプレッション数（キャンペーンのゴール設定時のみ）
- `総回数-インプレッション`: 配信された総回数
- `総回数-コンバージョン数`: 24時間以内にコンバージョンとして設定したイベントが実行された総回数（キャンペーンのゴール設定時のみ）
- `総回数-コンバージョン率`: 総コンバージョン数 / 総インプレッション数（キャンペーンのゴール設定時のみ）

### イベント起点プッシュ通知の配信結果

イベント起点プッシュ通知配信結果では、画面右上にある矢印ボタンをクリックすると、下記のデータを出力できます。
CSVファイルにはイベント起点プッシュ通知配信開始日から、効果測定の集計が完了している時点までのデータが出力されます。

カラム定義のうち、イベント起点プッシュ通知の配信結果にも含まれるカラム定義の詳細は、[配信結果](https://docs.repro.io/ja/dashboard/campaign/event-based-push-notification.md#event-based-push-measurement-result) もご覧ください。

**CSVファイルのカラム定義**

- `パターン`: パターン(A/Bテストのみ)
- `日付`: 集計日
- `配信数`: 配信されたユーザー数
- `開封数`: 通知を開封したユーザー数
- `直接開封数`: 直接開封したユーザー数
- `みなし開封数`: みなし開封したユーザー数
- `開封率`: 配信数のうち、開封したユーザーの割合
- `コンバージョン数`: プッシュ通知の [開封](https://docs.repro.io/ja/dashboard/campaign/event-based-push-notification.md#event-based-push-measurement-result) 後、1時間以内にゴールに設定したイベントを実行したユーザー数（キャンペーンのゴール設定時のみ）
- `コンバージョン率`: コンバージョン数 / 配信数（キャンペーンのゴール設定時のみ）

### Webプッシュ通知の配信結果

Webプッシュ通知の配信結果画面では、画面右上にある矢印ボタンをクリックすると、下記のデータをCSVファイルとしてダウンロードできます。
CSVファイルにはWebプッシュ通知配信開始日から、配信結果の集計が完了している時点までのデータが出力されます。

カラム定義のうち、Webプッシュ通知の配信結果にも含まれるカラム定義の詳細は、[配信結果](https://docs.repro.io/ja/dashboard/campaign/web-push-notification.md#web-push-measurement-result) もご覧ください。

**CSVファイルのカラム定義**

- `日付`: 集計日
- `配信数`: 通知を配信したユーザー数
- `開封数`: 通知を開封したユーザー数
- `直接開封数`: 通知をクリックしたユーザー数（ `押下数 + ボタン1押下数 + ボタン2押下数` のユニークユーザー数）
- `みなし開封数`: みなし開封したユーザー数
- `押下数`: 通知を押下したユーザー数
- `ボタン1押下数`: 通知のボタン1を押下したユーザー数
- `ボタン2押下数`: 通知のボタン2を押下したユーザー数
- `開封率`: 配信したユーザー数のうち、開封したユーザーの割合
- `コンバージョン数`: Webプッシュ通知の [開封](https://docs.repro.io/ja/dashboard/campaign/web-push-notification.md#web-push-measurement-result) 後、1時間以内にゴールに設定したイベントを実行したユーザー数
- `コンバージョン率`: コンバージョン数 / 配信数

---

## メールの配信上限

### 1日の配信上限

Reproのメール配信システム全体で1日の配信数の上限は **1000万通** になります。
 
他社が配信するメールの配信を含め、配信数の上限を超過した場合はメールの配信が行われません。
 

#### 本対応に関するお問い合わせ

カスタマーサクセス担当、もしくは管理画面のチャットよりお問い合わせください。

---

## リリースノート

* [SDK](https://docs.repro.io/ja/releases/sdk/index.md)
  * [iOS](https://docs.repro.io/ja/releases/sdk/ios/releases.md)
  * [Android](https://docs.repro.io/ja/releases/sdk/android/releases.md)
  * [Unity](https://docs.repro.io/ja/releases/sdk/unity/releases.md)
  * [Cordova](https://docs.repro.io/ja/releases/sdk/cordova/releases.md)
  * [Cocos2d-x](https://docs.repro.io/ja/releases/sdk/cocos2d-x/releases.md)
  * [React Native](https://docs.repro.io/ja/releases/sdk/react-native/releases.md)
  * [React Native (Expo)](https://docs.repro.io/ja/releases/sdk/expo/releases.md)
  * [Flutter](https://docs.repro.io/ja/releases/sdk/flutter/releases.md)
  * [各バージョンのサポート期間](https://docs.repro.io/ja/releases/sdk/end-of-life.md)
* [Web](https://docs.repro.io/ja/releases/web/index.md)
  * [リリースノート](https://docs.repro.io/ja/releases/web/releases.md)
  * [サポート期間](https://docs.repro.io/ja/releases/web/end-of-life.md)

* [ドメイン移行に伴う作業](https://docs.repro.io/ja/releases/change-domain/index.md)
* [FCMへの移行手順](https://docs.repro.io/ja/releases/migration-to-fcm/index.md)

---

## リリースノート (SDK)

* [iOS](https://docs.repro.io/ja/releases/sdk/ios/releases.md)
* [Android](https://docs.repro.io/ja/releases/sdk/android/releases.md)
* [Unity](https://docs.repro.io/ja/releases/sdk/unity/releases.md)
* [Cordova](https://docs.repro.io/ja/releases/sdk/cordova/releases.md)
* [Cocos2d-x](https://docs.repro.io/ja/releases/sdk/cocos2d-x/releases.md)
* [React Native](https://docs.repro.io/ja/releases/sdk/react-native/releases.md)
* [React Native (Expo)](https://docs.repro.io/ja/releases/sdk/expo/releases.md)
* [Flutter](https://docs.repro.io/ja/releases/sdk/flutter/releases.md)
* [各バージョンのサポート期間](https://docs.repro.io/ja/releases/sdk/end-of-life.md)

---

## React Native SDK リリースノート

* [React Native SDK 更新手順](https://docs.repro.io/ja/releases/sdk/react-native/upgrade.md)
  * [React NativeのAuto Linkingをご利用中の場合](https://docs.repro.io/ja/releases/sdk/react-native/upgrade.md#react-nativeauto-linking)



### 4.3.1 (2026/07/01)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.24.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-24-1)
  - [Android SDK 5.24.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-24-0)



### 4.3.0 (2026/04/01)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [Android SDK 5.22.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-22-0)



### 4.2.0 (2026/03/05)

修正

- React Native New Architecture を有効にしたiOSアプリにおいて、ユーザープロフィールが正しく登録されない場合がある問題を修正しました。

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.23.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-23-0)
  - [Android SDK 5.21.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-21-0)



### 4.1.1 (2026/01/27)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.22.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-22-1)
  - [Android SDK 5.20.7](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-20-7)

##### WARNING
React Native New Architecture を有効にしたアプリにおいてユーザープロフィールが正しく登録されない可能性があるため、このバージョンのご利用は推奨しません。代わりに、 [React Native SDK 4.2.0](#react-native-4-2-0) 以降のバージョンをご利用ください。



### 4.1.0 (2025/12/15)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.22.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-22-0)

##### WARNING
React Native New Architecture を有効にしたアプリにおいてユーザープロフィールが正しく登録されない可能性があるため、このバージョンのご利用は推奨しません。代わりに、 [React Native SDK 4.2.0](#react-native-4-2-0) 以降のバージョンをご利用ください。



### 4.0.4 (2025/11/19)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [Android SDK 5.20.4](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-20-4)

##### WARNING
React Native New Architecture を有効にしたアプリにおいてユーザープロフィールが正しく登録されない可能性があるため、このバージョンのご利用は推奨しません。代わりに、 [React Native SDK 4.2.0](#react-native-4-2-0) 以降のバージョンをご利用ください。



### 4.0.3 (2025/11/14)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.21.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-21-1)
  - [Android SDK 5.20.3](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-20-3)

##### WARNING
React Native New Architecture を有効にしたアプリにおいてユーザープロフィールが正しく登録されない可能性があるため、このバージョンのご利用は推奨しません。代わりに、 [React Native SDK 4.2.0](#react-native-4-2-0) 以降のバージョンをご利用ください。



### 4.0.2 (2025/10/23)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [Android SDK 5.20.2](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-20-2)

##### WARNING
React Native New Architecture を有効にしたアプリにおいてユーザープロフィールが正しく登録されない可能性があるため、このバージョンのご利用は推奨しません。代わりに、 [React Native SDK 4.2.0](#react-native-4-2-0) 以降のバージョンをご利用ください。



### 4.0.1 (2025/09/29)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [Android SDK 5.20.1](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-20-1)

##### WARNING
React Native New Architecture を有効にしたアプリにおいてユーザープロフィールが正しく登録されない可能性があるため、このバージョンのご利用は推奨しません。代わりに、 [React Native SDK 4.2.0](#react-native-4-2-0) 以降のバージョンをご利用ください。



### 4.0.0 (2025/07/30)

新機能

- New Architecture をサポートしました。

##### NOTE
以前のバージョンのReact Native SDKからアップデートを行う場合、キャッシュが残っていることでビルドに失敗する可能性があります。ビルドに失敗する場合はキャッシュを削除してアップデートをしてください。

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.21.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-21-0)
  - [Android SDK 5.20.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-20-0)

##### WARNING
React Native New Architecture を有効にしたアプリにおいてユーザープロフィールが正しく登録されない可能性があるため、このバージョンのご利用は推奨しません。代わりに、 [React Native SDK 4.2.0](#react-native-4-2-0) 以降のバージョンをご利用ください。



### 3.24.0 (2025/05/28)

新機能

- WebView内で任意のイベントのトラッキングやユーザープロフィールの設定を行うことができるようになりました。



### 3.23.0 (2025/04/25)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.20.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-20-0)
  - [Android SDK 5.19.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-19-0)



### 3.22.0 (2024/12/26)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.19.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-19-0)
  - [Android SDK 5.18.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-18-0)



### 3.21.1 (2024/10/30)

修正

- UXオプティマイザー（β）機能において `fetch` APIでタイムアウト時間を指定した際、iOSの場合のみ単位を「秒」として解釈している問題を修正しました。

##### WARNING
- 修正によりiOS, Android共に単位は「ミリ秒」となります。そのためiOSアプリにおいて既に `fetch` APIを使用している場合は値の変更が必要となる場合があります。
- APIの利用方法の詳細は [アプリ内パラメーター](https://docs.repro.io/ja/dev/sdk/remote-config.md) をご覧ください。

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [Android SDK 5.17.1](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-17-1)



### 3.21.0 (2024/10/03)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.18.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-18-0)
  - [Android SDK 5.17.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-17-0)



### 3.20.0 (2024/08/30)

新機能

- プッシュ通知の利用時に使用する `setPushDeviceTokenString` (iOS) および `setPushRegistrationID` (Android) に代わるAPI `setPushToken` (iOS/Android共用) を追加しました。
  - 詳細は [プッシュ通知 (React Native)](https://docs.repro.io/ja/dev/sdk/push-notification/react-native.md) を参照してください。



### 3.19.0 (2024/07/11)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.17.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-17-0)
  - [Android SDK 5.16.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-16-0)



### 3.18.0 (2024/05/17)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.16.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-16-0)
  - [Android SDK 5.15.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-15-0)



### 3.17.0 (2024/04/30)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.15.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-15-0)
  - [Android SDK 5.14.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-14-0)



### 3.16.0 (2024/01/19)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.14.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-14-0)
  - [Android SDK 5.13.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-13-0)



### 3.15.1 (2023/12/22)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.13.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-13-1)



### 3.15.0 (2023/11/17)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.13.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-13-0)
  - [Android SDK 5.12.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-12-0)



### 3.14.0 (2023/10/16)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.12.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-12-0)
  - [Android SDK 5.11.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-11-0)



### 3.13.0 (2023/09/12)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.11.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-11-1)
  - [Android SDK 5.10.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-10-0)



### 3.12.0 (2023/06/13)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.11.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-11-0)
  - [Android SDK 5.9.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-9-0)



### 3.11.0  (2023/03/08)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.9.5](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-9-5)
  - [Android SDK 5.8.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-8-0)



### 3.10.3  (2023/02/14)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.9.4](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-9-4)



### 3.10.2  (2022/12/28)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.9.3](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-9-3)
  - [Android SDK 5.7.2](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-7-2)



### 3.10.1  (2022/10/05)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.9.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-9-1)
  - [Android SDK 5.7.1](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-7-1)



### 3.10.0  (2022/08/31)

新機能

- ユニバーサルリンク･アプリリンクに対応するためのコールバック処理の記述が可能になりました。
  - 詳細は [こちら](https://docs.repro.io/ja/dev/sdk/push-notification/react-native.md#universal-link-guide-react-native) をご覧ください。

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.9.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-9-0)
  - [Android SDK 5.7.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-7-0)



### 3.9.0  (2022/06/08)

修正

- パッケージマネージャに関連した問題により、AndroidアプリにてSDKを導入できない問題を修正しました。
- Gradleバージョン7.0以上を使用している環境でSDKをインポートできない問題を修正しました。

##### WARNING
このバージョンから、Gradle 3.4未満を利用している環境ではSDKを適用できなくなります。3.4未満をご利用の場合はGradleのバージョンアップを検討してください。



### 3.8.0  (2022/04/14)

変更

- サポート品質の向上のため、クロスプラットフォーム環境におけるSDKの情報を取得する機能を追加しました。
- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.8.3](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-8-3)
  - [Android SDK 5.6.3](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-6-3)



### 3.7.0  (2021/12/07)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.8.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-8-0)
  - [Android SDK 5.6.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-6-0)



### 3.6.0  (2021/10/15)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.7.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-7-0)



### 3.5.0  (2021/08/06)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.6.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-6-0)
  - [Android SDK 5.5.1](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-5-1)



### 3.4.0  (2021/06/03)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.5.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-5-1)
  - [Android SDK 5.4.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-4-0)



### 3.3.1  (2021/04/16)

変更

- UXオプティマイザー機能（クローズドβ）の `getValue` API をキーが登録されていない項目に対して呼び出すとクラッシュする不具合を修正しました。



### 3.3.0  (2021/03/09)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.4.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-4-0)
  - [Android SDK 5.3.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-3-0)



### 3.2.0  (2021/02/02)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.3.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-3-0)
  - [Android SDK 5.2.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-2-0)



### 3.1.1  (2020/12/23)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.2.12](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-2-12)
  - [Android SDK 5.1.9](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-1-9)



### 3.1.0 (2020/11/06)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.2.2](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-2-2)
  - [Android SDK 5.1.3](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-1-3)

修正

- ニュースフィード取得時に稀にクラッシュする問題を修正しました。



### 3.0.0 (2020/08/21)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.1.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-1-0)
  - [Android SDK 5.1.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-1-0)
- ニュースフィード機能およびAIレコメンド・アプリ内メッセージ連携機能（クローズドβ）に関するAPIを追加しました。
  - ニュースフィード機能についての詳細は [こちら](https://docs.repro.io/ja/dev/sdk/newsfeed.md) をご覧ください。



### 2.3.0  (2020/07/08)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 4.7.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-4-7-1)
  - [Android SDK 4.4.1](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-4-4-1)
- UXオプティマイザー機能（クローズドβ）に関するAPIを追加しました。
  - 詳細は [こちら](https://docs.repro.io/ja/dev/sdk/remote-config/react-native.md) をご覧ください。



### 2.2.0  (2020/03/26)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 4.7.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-4-7-0)
  - [Android SDK 4.4.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-4-4-0)



### 2.1.0  (2019/10/28)

変更

- React Native 0.60.0で導入された [Auto Linking](https://facebook.github.io/react-native/blog/2019/07/03/version-60#native-modules-are-now-autolinked) に対応しました。
  - React Native 0.60.0以上をご利用中の場合は [こちらの更新手順](upgrade.html#react-native-0-60-0) をご覧ください。
- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 4.3.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-4-3-0)
  - [Android SDK 4.2.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-4-2-0)



### 2.0.0  (2019/05/29)

変更

- 動画機能に関する以下のAPIを削除しました。
  - `ReproMaskView`
  - `startRecording`
  - `stopRecording`
  - `pauseRecording`
  - `resumeRecording`
  - `maskWithRect`
  - `unmask`
  - `maskWithRect`
  - `unmaskForKey`
  - `forceCaptureOnMainThread`
  - `enableRecordingWhileViewAnimations`
  - `disableRecordingWhileViewAnimations`
- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 4.0.3](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-4-0-3)
  - [Android SDK 4.0.4](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-4-0-4)



### 1.2.0  (2019/04/05)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 3.3.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-3-3-0)



### 1.1.3 (2019/03/14)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 3.2.2](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-3-2-2)
- オプトアウト機能用のAPIを追加しました。
  - 詳細は [こちら](https://docs.repro.io/ja/dev/sdk/optout/index.md) をご覧ください。
- iOSモジュールの `HEADER_SEARCH_PATHS` にCocoapods用のパスを追加しました。



### 1.1.0 (2019/02/15)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 3.2.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-3-2-0)
  - [Android SDK 3.3.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-3-3-0)
- 動画機能に関する主要なコードを削除し、動画機能が動作しないようにしました。以下のAPIを呼び出しても問題ありませんが何も実行されません。
  - `startRecording`
  - `stopRecording`
  - `pauseRecording`
  - `resumeRecording`
  - `forceCaptureOnMainThread`
  - `enableRecordingWhileViewAnimations`
  - `disableRecordingWhileViewAnimations`
  - `maskWithRect`
  - `unmask`
  - `NativeReproMaskView`

  #### WARNING
  録画関連APIは削除されました。2019年5月22日現在、これを利用することはできません。



### 1.0.0 (2018/11/20)

正式版をリリースしました。

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 3.0.4](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-3-0-4)
  - [Android SDK 3.1.1](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-3-1-1)
- 画面遷移時にマスクの有効 / 無効を切り替えられるようになりました。



### 0.1.0 β (2018/10/10)

下記 SDK が同梱されている React Native SDK をリリースしました。

- [iOS SDK 3.0.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-3-0-1)
- [Android SDK 3.0.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-3-0-0)

β版の注意事項は以下の通りです。

- マスクを含む画面から別な画面に遷移した後、マスクが消えずに残り続ける場合があります。

---

## React Native SDK 更新手順

下記のコマンドを実行してください。

```sh
npm update react-native-repro
```

各バージョン毎に追加の更新手順が必要な場合は、 [React Native SDK リリースノート](https://docs.repro.io/ja/releases/sdk/react-native/releases.md) に記載しています。

### React NativeのAuto Linkingをご利用中の場合

Repro React Native SDK 2.1.0 以上では、React Native 0.60.0 で導入された [Auto Linking](https://facebook.github.io/react-native/blog/2019/07/03/version-60#native-modules-are-now-autolinked) に対応しています。

Auto Linkingをご利用中のアプリでは、Repro React Native SDK 2.1.0未満から2.1.0以上へのアップグレード後、以下の手順を実行してRepro React Nativeに対するAuto Linkingを有効にしてください。

まず、`react-native unlink` を実行して不要な設定を削除します。

```sh
react-native unlink react-native-repro
```

#### iOS

Xcodeプロジェクトを開き、導入手順で追加した [Build Phases](../../../dev/sdk/getstarted/react-native.html#resource-bundle) と [Framework Search Path](../../../dev/sdk/getstarted/react-native.html#framework-path) を削除してください。その後 `pod install` を実行してください。

```sh
cd ios

pod install
```

なお、`pod install` を実行すると、以下のような警告が出る場合があります。

```text
[!] The `<APPNAME> [<TARGET>]` target overrides the `FRAMEWORK_SEARCH_PATHS` build setting defined in `Pods/<longpath>.xcconfig'. This can lead to problems with the CocoaPods installation
    - Use the `$(inherited)` flag, or
    - Remove the build settings from the target.
```

この場合、警告で指示されている通りXcodeプロジェクトのFramework Search Pathに `$(inherited)` を追加してください。

#### Android

導入手順で追加した [Mavenリポジトリへの参照](../../../dev/sdk/getstarted/react-native.html#android) は **削除せずに残してください。** Mavenリポジトリへの参照は、Auto Linkingの有効/無効に関わらず必要となります。

---

<script>
  window.location.href = "../remote-config.html";
</script>

---

## React Native (Expo) Plugin リリースノート



### 1.1.0 (2025/12/15)

新機能

- app.json ファイルに設定できる `iosHtmlInAppBaseUrl` を追加しました。詳細は [App-Bound Domains を有効にしている場合（iOSのみ）](https://docs.repro.io/ja/dev/sdk/in-app-message.md#html-inapp-message-custom-base-url) を参照してください。



### 1.0.1 (2024/10/06)

修正

- 特定の場合において EAS Build が失敗する問題を修正しました。



### 1.0.0 (2024/08/30)

新機能

- 正式版をリリースしました。

---

## Flutter Package リリースノート

* [Flutter package 更新手順](https://docs.repro.io/ja/releases/sdk/flutter/upgrade.md)



### 3.20.1 (2026/07/01)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.24.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-24-1)
  - [Android SDK 5.24.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-24-0)



### 3.20.0 (2026/04/01)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [Android SDK 5.22.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-22-0)



### 3.19.0 (2026/03/05)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.23.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-23-0)
  - [Android SDK 5.21.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-21-0)



### 3.18.2 (2026/02/18)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [Android SDK 5.20.9](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-20-9)
- SDKのcompileSdkVersionを35に変更しました。
- SDKのminSdkVersionを21に変更しました。



### 3.18.1 (2026/01/27)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.22.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-22-1)
  - [Android SDK 5.20.7](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-20-7)



### 3.18.0 (2025/12/15)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.22.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-22-0)



### 3.17.5 (2025/11/19)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [Android SDK 5.20.4](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-20-4)



### 3.17.4 (2025/11/14)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.21.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-21-1)
  - [Android SDK 5.20.3](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-20-3)



### 3.17.3 (2025/10/23)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [Android SDK 5.20.2](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-20-2)



### 3.17.2 (2025/09/29)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [Android SDK 5.20.1](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-20-1)



### 3.17.0 (2025/07/28)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.21.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-21-0)
  - [Android SDK 5.20.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-20-0)



### 3.16.1 (2025/07/10)

修正

- アプリ内パラメーター機能において、パラメーターが存在しないキーを指定して値を取得しようとする際にアプリケーションがクラッシュする場合がある問題を修正しました。



### 3.16.0 (2025/05/23)

新機能

- WebView内で任意のイベントのトラッキングやユーザープロフィールの設定を行うことができるようになりました。



### 3.15.0 (2025/04/25)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.20.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-20-0)
  - [Android SDK 5.19.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-19-0)



### 3.14.0 (2025/03/28)

変更

- Android v1 embedding の PluginRegistry が Flutter 3.29 で削除されたことに伴い、Repro Flutter Pluginから PluginRegistry を使用しているコードを削除しました。

##### WARNING
この変更により、Android v1 embeddingを使用しているアプリ(特にFlutter バージョン1.xなど)ではプラグインを利用できなくなることに注意してください。
Android v1 embeddingを使用している場合は引き続きFlutter Package 3.13.0以下を利用するか、アプリにてご利用のFlutter SDKのバージョンアップおよびAndroid embedding v2の対応を検討してください。



### 3.13.0 (2024/12/26)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.19.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-19-0)
  - [Android SDK 5.18.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-18-0)



### 3.12.1 (2024/10/30)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [Android SDK 5.17.1](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-17-1)



### 3.12.0 (2024/10/03)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.18.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-18-0)
  - [Android SDK 5.17.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-17-0)



### 3.11.0 (2024/08/29)

変更

- Android環境において、特定の場合に `setOpenUrlCallback` でセットしたcallbackが動作しない問題を解消しました。



### 3.10.0 (2024/07/11)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.17.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-17-0)
  - [Android SDK 5.16.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-16-0)



### 3.9.0 (2024/05/17)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.16.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-16-0)
  - [Android SDK 5.15.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-15-0)



### 3.8.0 (2024/04/30)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.15.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-15-0)
  - [Android SDK 5.14.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-14-0)



### 3.7.0 (2024/01/19)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.14.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-14-0)
  - [Android SDK 5.13.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-13-0)



### 3.6.1 (2023/12/22)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.13.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-13-1)



### 3.6.0 (2023/11/17)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.13.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-13-0)
  - [Android SDK 5.12.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-12-0)



### 3.5.0 (2023/10/16)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.12.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-12-0)
  - [Android SDK 5.11.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-11-0)



### 3.4.0 (2023/09/12)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.11.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-11-1)
  - [Android SDK 5.10.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-10-0)



### 3.3.0 (2023/06/13)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.11.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-11-0)
  - [Android SDK 5.9.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-9-0)



### 3.2.0 (2023/03/08)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.9.5](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-9-5)
  - [Android SDK 5.8.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-8-0)



### 3.1.3 (2023/02/14)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.9.4](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-9-4)



### 3.1.2 (2022/12/28)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.9.3](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-9-3)
  - [Android SDK 5.7.2](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-7-2)



### 3.1.1 (2022/10/05)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.9.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-9-1)
  - [Android SDK 5.7.1](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-7-1)



### 3.1.0 (2022/08/31)

新機能

- ユニバーサルリンク･アプリリンクに対応するためのコールバック処理の記述が可能になりました。
  - 詳細は [こちら](https://docs.repro.io/ja/dev/sdk/push-notification/flutter.md#universal-link-guide-flutter) をご覧ください。

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.9.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-9-0)
  - [Android SDK 5.7.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-7-0)



### 3.0.0 (2022/06/03)

変更

- プラグインをDart 2.12より適用されたSound null safety機能に対応しました。

##### WARNING
この変更により、Sound null safety機能を有効にしていないアプリ(特にFlutter バージョン1.xなど)ではプラグインを利用できなくなることに注意してください。
Sound null safety機能を有効にしていない場合は引き続きFlutter Package 2.1.0以下を利用するか、アプリにてご利用のFlutter SDKのバージョンアップおよびSound null safety機能の有効化を検討してください。

新機能

- Android embedding v2によるプラグインの適用に対応しました。
  - 詳細は [Upgrading pre 1.12 Android projects · flutter/flutter Wiki](https://github.com/flutter/flutter/wiki/Upgrading-pre-1.12-Android-projects) を参照してください。
- プッシュ通知受信時の動作をカスタマイズするためのAPIを追加しました。
  - 詳細は [こちら](https://docs.repro.io/ja/dev/sdk/push-notification/android.md) をご覧ください。



### 2.1.0 (2022/04/14)

変更

- サポート品質の向上のため、クロスプラットフォーム環境におけるSDKの情報を取得する機能を追加しました。
- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.8.3](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-8-3)
  - [Android SDK 5.6.3](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-6-3)



### 2.0.1 (2022/03/01)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.8.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-8-1)
  - [Android SDK 5.6.2](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-6-2)
- 特定の場合に `enableInAppMessagesOnForegroundTransition` メソッドが動作しない問題を修正しました。



### 2.0.0 (2021/12/07)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.8.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-8-0)
  - [Android SDK 5.6.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-6-0)
- `getNewsFeeds` メソッドのシグニチャが変更されました。詳細は [開発ガイド](https://docs.repro.io/ja/dev/sdk/newsfeed.md) を参照してください。
- `RenderMode` および `TransparencyMode` の設定値によりアプリ内メッセージが正常に表示されない問題を修正しました。



### 1.6.0 (2021/11/01)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.7.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-7-1)



### 1.5.0 (2021/08/03)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.6.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-6-0)
  - [Android SDK 5.5.1](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-5-1)



### 1.4.0 (2021/06/03)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.5.1](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-5-1)
  - [Android SDK 5.4.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-4-0)



### 1.3.0 (2021/03/10)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.4.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-4-0)
  - [Android SDK 5.3.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-3-0)



### 1.2.0 (2021/02/09)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.3.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-3-0)
  - [Android SDK 5.2.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-2-0)



### 1.1.0 (2020/11/02)

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.2.2](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-2-2)
  - [Android SDK 5.1.3](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-1-3)



### 1.0.0 (2020/08/26)

正式版をリリースしました。

変更

- SDKを更新しました。変更点の詳細は以下のリンク先をご確認ください。
  - [iOS SDK 5.1.0](https://docs.repro.io/ja/releases/sdk/ios/releases.md#ios-5-1-0)
  - [Android SDK 5.1.0](https://docs.repro.io/ja/releases/sdk/android/releases.md#android-5-1-0)
- ニュースフィード機能、UXオプティマイザー機能（ベータ版）および AIレコメンド・アプリ内メッセージ連携機能（ベータ版）に関するAPIを追加しました。各機能の詳細は以下を参照してください。
  - [ニュースフィード機能](https://docs.repro.io/ja/dev/sdk/newsfeed.md)
  - [UXオプティマイザー機能](https://docs.repro.io/ja/dev/sdk/remote-config/android.md)
  - [AIレコメンド・アプリ内メッセージ連携機能](https://docs.repro.io/ja/dashboard/campaign/silver-egg-recommend-message.md)
- 旧バージョンより、全体的にAPIのシグニチャが変更されました。変更後のAPIの使用方法については [開発ガイドのサンプル](https://docs.repro.io/ja/dev/sdk/getstarted/flutter.md) を参照してください。

---

## Flutter package 更新手順

最新の Flutter package を参照するよう `pubspec.yaml` を変更してください。

```yaml
dependencies:
  flutter:
    sdk: flutter
  ...
  repro_flutter: ^3.18.2
```

次に以下のコマンドを実行してください。

```sh
$ flutter pub get
or
$ flutter pub upgrade
```

また Android SDK および iOS SDK の更新を行う必要があります。

### Android

`app/build.gradle` を以下のように変更してください。

```groovy
 dependencies {
     ...
     implementation 'io.repro:repro-android-sdk:5.24.0'
     ...
 }
```

### iOS

プロジェクトのルートディレクトリで以下のコマンドを実行してください。

```sh
$ cd ios
$ pod update Repro
```

---

<script>
  window.location.href = "../remote-config.html";
</script>

---

## 各バージョンのサポート期間

サポート対象外となったSDKでは告知なく該当バージョンへのデータ収集、メッセージ配信などが行われなくなります。バージョンごとの動作保証期間終了日をご確認の上、SDKのアップグレードをお願い致します。

##### NOTE
- 原則として、該当バージョンのリリース日から2年間がサポート期間となります。以下一覧にないSDKのリリース日はリリースノートをご確認ください。

### iOS SDK

| バージョン | 動作保証期間終了日 |
| --- | --- |
| ~5.0.0 | 2022/06/19 |
| ~5.0.1 | 2022/06/25 |
| ~5.0.2 | 2022/08/31 |
| ~5.1.0 | 2022/09/15 |
| ~5.2.0 | 2022/10/07 |
| ~5.2.2 | 2022/10/22 |
| ~5.2.8 | 2022/11/25 |
| ~5.2.12 | 2022/12/21 |
| ~5.3.0 | 2023/02/01 |
| ~5.4.0 | 2023/03/08 |
| ~5.5.0 | 2023/05/20 |
| ~5.5.3 | 2023/06/17 |

### Android SDK

| バージョン | 動作保証期間終了日 |
| --- | --- |
| ~5.0.0 | 2022/06/19 |
| ~5.0.1 | 2022/06/24 |
| ~5.0.2 | 2022/06/27 |
| ~5.0.3 | 2022/07/01 |
| ~5.0.4 | 2022/08/31 |
| ~5.1.0 | 2022/09/15 |
| ~5.1.2 | 2022/10/19 |
| ~5.1.3 | 2022/10/22 |
| ~5.1.4 | 2022/11/18 |
| ~5.1.7 | 2022/12/17 |
| ~5.1.9 | 2022/12/23 |
| ~5.1.12 | 2023/01/19 |
| ~5.2.0 | 2023/02/01 |
| ~5.3.0 | 2023/03/08 |
| ~5.4.0 | 2023/05/20 |
| ~5.4.1 | 2023/06/16 |

### Unity Package, Cordova Plugin, Cocos2d-x SDK, React Native SDK, Flutter Package

同梱されているiOS SDKおよびAndroid SDKのサポート期間に準じます。各プラットフォームのリリースノートをご覧ください。

- [Unity Package リリースノート](https://docs.repro.io/ja/releases/sdk/unity/releases.md)
- [Cordova Plugin リリースノート](https://docs.repro.io/ja/releases/sdk/cordova/releases.md)
- [Cocos2d-x SDK リリースノート](https://docs.repro.io/ja/releases/sdk/cocos2d-x/releases.md)
- [React Native SDK リリースノート](https://docs.repro.io/ja/releases/sdk/react-native/releases.md)
- [Flutter Package リリースノート](https://docs.repro.io/ja/releases/sdk/flutter/releases.md)

---

## リリースノート (Web)

* [リリースノート](https://docs.repro.io/ja/releases/web/releases.md)
* [サポート期間](https://docs.repro.io/ja/releases/web/end-of-life.md)

---

js-web

## リリースノート



### 2.26.5 (2026/06/19)

修正

- 軽微な不具合を修正しました。



### 2.26.4 (2026/02/09)

修正

- ユーザープロフィールのセットで発火するトリガーをセット操作のみに修正しました。詳細は [ユーザープロフィールのセットによってトリガーを実行する](https://docs.repro.io/ja/dashboard/campaign/web-message.md#web-message-triggered-by-set-userprofile) を参照してください。



### 2.26.3 (2026/02/02)

修正

- 軽微な不具合を修正しました。



### 2.26.2 (2026/01/27)

修正

- 軽微な不具合を修正しました。



### 2.26.1 (2025/12/02)

修正

- 軽微な不具合を修正しました。



### 2.26.0 (2025/07/25)

新機能

- ユーザープロフィールの設定方法として、条件付きセット操作、増減操作、削除の操作が追加されました。詳細は [ユーザープロフィール](https://docs.repro.io/ja/dev/sdk/user-profile.md) を参照してください。



### 2.25.2 (2025/06/23)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.25.1 (2025/06/04)

修正

- 同じ値で連続して `setUserID` を呼び出した際に内部状態がリセットされないように変更しました。



### 2.25.0 (2025/04/22)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.24.0 (2025/03/12)

新機能

- Web SDKが記録するCookieのドメイン属性を指定するオプションを追加しました。

修正

- SPA モードにおけるBack/Forward Cacheの扱いを修正しました。



### 2.23.0 (2024/09/20)

修正

- データ収集における信頼性向上のための軽微な修正を行いました。



### 2.22.13 (2024/03/26)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.22.12 (2024/03/12)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.22.11 (2024/02/21)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.22.10 (2024/02/15)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.22.9 (2024/01/17)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.22.8 (2023/12/26)

修正

- データ収集における信頼性向上のための軽微な修正を行いました。



### 2.22.7 (2023/09/11)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.22.6 (2023/05/16)

修正

- iOSとmacOSのWeb Push通知に対応しました。



### 2.22.5 (2022/11/22)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.22.4 (2022/11/09)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.22.3 (2022/10/28)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.22.2 (2022/10/11)

新機能

- version API が追加されました

修正

- SetUserID が行わた際のイベントバッファの取り扱いを改善しました
- メッセージの同時表示チェックを厳密に行うようにしました



### 2.22.1 (2022/09/20)

修正

- Firefox iOS での動作を修正しました
- WebPush 表示・クリック時のセッションハンドリングを改善しました



### 2.22.0 (2022/08/10)

新機能

- サーバ側から動作オプションを指定できる機能を追加しました



### 2.21.10 (2022/08/10)

修正

- 最新の Android 版 Chrome が常に webview として判定される問題を修正しました。
- SPA モードで history.pushState, history.replaceState の上書きを行えるように変更しました。



### 2.21.9 (2022/07/27)

修正

- SDKの信頼性向上のための軽微な修正を行いました。
- SPA モードで複数回及び無限回のメッセージの挙動を調整可能にしました。



### 2.21.8 (2022/07/20)

修正

- SDKの信頼性向上のための軽微な修正を行いました。
- ページ内リンククリック時のメッセージ挙動を調整可能にしました。



### 2.21.7 (2022/07/12)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.21.6 (2022/07/06)

修正

- モバイル版 Firefox での動作を修正しました
- SPAモードで自動的にメッセージを閉じるオプションを追加しました
- SDKの信頼性向上のための軽微な修正を行いました



### 2.21.5 (2022/06/29)

修正

- SPAモードを有効にした際、不要な警告が出力されていた問題を修正しました



### 2.21.4 (2022/05/31)

修正

- Internet Explorer 11 をWeb SDKのサポート対象外ブラウザとして扱うように変更しました



### 2.21.3 (2022/05/26)

修正

- プレビューモードの互換性に関して軽微な修正を行いました
- カスタムJavaScript用のインターフェースを更新しました



### 2.21.2 (2022/05/20)

修正

- プレビューモードでページ遷移時の互換性を向上させました
- カスタムJavaScript用のインターフェースを更新しました



### 2.21.1 (2022/04/18)

修正

- クロスドメイン機能の安定性を向上させる軽微な修正を行いました。



### 2.21.0 (2022/04/06)

新機能

- カスタムJavaScript用のインターフェースを追加しました



### 2.20.11 (2022/04/05)

修正

- 埋め込みメッセージや吹き出しメッセージなどのプレビュー時の挙動を改善しました。
- SPA モードで linker_domain が指定されている場合の挙動を修正しました。



### 2.20.10 (2022/03/16)

修正

- SDKの信頼性向上のための軽微な修正を行いました。
- Windows IE で一部機能の動作に問題があった点を修正しました。
- ユーザープロフィールのセット時、日付型に不正な値を渡した場合のエラーハンドリングを改善しました。



### 2.20.9 (2022/01/17)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.20.8 (2022/01/07)

修正

- SPAにおけるメッセージの動作に不具合があるケースを修正しました。
- WebView環境での動作判定の精度を向上させる修正を行いました。



### 2.20.7 (2021/10/25)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.20.6 (2021/10/18)

修正

- SDKが書き込むCookieのSameSite属性に Lax を指定する変更を行いました。
- 特定条件下でイベントのトラッキング及びメッセージ表示が行われなくなる問題を修正しました。



### 2.20.2 (2021/07/13)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.20.1 (2021/06/28)

修正

- クロスドメイン・トラッキング機能においてサイト内リンクに誤ってパラメータが付与されるケースがあるのを修正しました。



### 2.20.0 (2021/06/17)

新機能

- SPAなサイトでより正確にイベントをトラックしたりメッセージを表示できる「SPAモード」を追加しました。



### 2.19.4 (2021/06/15)

修正

- クロスドメイン・トラッキング機能においてサイト内リンクに誤ってパラメータが付与されるケースがあるのを修正しました。



### 2.19.3 (2021/06/08)

修正

- SDKの信頼性向上のための軽微な修正を行いました。
- イベントトリガーの一部のケースにおける条件比較の修正を行いました。
- クロスドメイン・トラッキングにおけるサブドメインの扱いについて一部のケースの挙動を修正しました。



### 2.19.2 (2021/05/18)

修正

- カウントダウンのメッセージが配信された際に、コントロールグループを利用したメッセージの効果測定が意図した値にならないケースがある問題を修正しました。



### 2.19.1 (2021/04/26)

修正

- メッセージのコントロールグループならびに表示位置に関連する仕様を変更しました。変更内容の詳細は [こちら](https://reproio.zendesk.com/hc/ja/articles/900006761763) を参照してください。



### 2.19.0 (2021/04/26)

新機能

- Webメッセージのトリガーとして使用できる条件を追加しました。



### 2.18.0 (2021/04/22)

修正

- パフォーマンスの向上のための修正をしました。



### 2.17.9 (2021/04/07)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.17.8 (2021/03/24)

修正

- イベントをトラックした際にSDKが自動でセットするプロパティから **og_url** と **canonical_url** を削除しました



### 2.17.7 (2021/03/12)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.17.6 (2021/03/03)

修正

- ChromeやSafariにおいて、BFCacheから復元されたページ上での信頼性を向上させる軽微な修正を行いました。



### 2.17.5 (2021/02/18)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.17.4 (2021/02/09)

修正

- 複数タブで同時にアクセスした際に、一時的に別のユーザーとして識別されうることがある問題を修正しました



### 2.17.3 (2021/02/05)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.17.2 (2021/02/01)

修正

- イベント名ならびにユーザープロフィール名の先頭もしくは末尾にある半角スペースなどの文字を自動で取り除くように修正しました



### 2.17.1 (2021/01/25)

修正

- 一部のケースにおいて、埋め込みメッセージの挙動が意図通りにならない問題を修正しました
- SDKの信頼性向上のための軽微な修正を行いました。



### 2.17.0 (2021/01/20)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.16.8 (2021/01/13)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.16.7 (2020/12/14)

修正

- Webメッセージのボタンをクリックしても閉じないように制御できるようになりました



### 2.16.5 (2020/11/30)

修正

- SDKの信頼性向上のための軽微な修正を行いました。
- SDKファイルのHTTP Cacheを5分に変更しました。



### 2.16.4 (2020/11/17)

新機能

- Webメッセージのボタンを現在のタブで開くか新規タブで開くかを選択できるようになりました



### 2.16.3 (2020/11/11)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.15.9 (2020/09/28)

修正

- メッセージの表示トリガーとして指定されたイベントが複数回連続してトラックされた際に、メッセージが意図した挙動にならないケースがある問題を修正しました。



### 2.15.6 (2020/08/24)

修正

- 一部のブラウザにおいてタイムゾーン情報が取得できずデータのアップロードが正常に完了しない問題を修正しました。



### 2.15.5 (2020/08/18)

修正

- 一部のAndroid端末においてWeb SDKが正しく動作しない問題を修正しました。
- 収集したデータをアップロードする際のフォーマットを一部変更しました。



### 2.15.4 (2020/08/12)

修正

- ソーシャルプルーフのメッセージが配信された際に、コントロールグループを利用したメッセージの効果測定が意図した値にならないケースがある問題を修正しました。



### 2.15.3 (2020/07/28)

修正

- カスタムメッセージのJavaScriptが配信された際に、コントロールグループを利用したメッセージの効果測定が意図した値にならないケースがある問題を修正しました。



### 2.15.2 (2020/07/20)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.15.1 (2020/07/16)

修正

- カスタムメッセージのJavaScriptが一部のケースで正常に動作しないバグを修正しました。



### 2.15.0 (2020/07/06)

修正

- パフォーマンス向上のための修正を行いました。



### 2.14.2 (2020/06/19)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.13.4 (2020/05/14)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.13.3 (2020/05/12)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.13.2 (2020/05/07)

修正

- Scoped CSS機能を利用する際に一部のブラウザで正常に動作いないバグを修正しました。



### 2.13.0 (2020/04/06)

新機能

- 「カスタムHTMLメッセージ（ベータ版）」で作成したメッセージのスタイリングをメッセージ内に閉じ込めるScoped CSS機能をリリースしました。



### 2.12.0 (2020/03/30)

新機能

- カスタムメッセージでJavaScriptの実行をサポートしました
- カスタムメッセージでsourceタグとaria系の属性が利用できるようになりました



### 2.11.0 (2020/03/12)

修正

- カスタムメッセージ内で **data-repro--primary-btn** 属性と **data-repro--secondary-btn** 属性を複数のDOM要素に設定できるようになりました。



### 2.10.0 (2020/02/03)

新機能

- ソーシャルプルーフメッセージ機能（クローズドβ）を追加しました。



### 2.9.4 (2020/01/20)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.9.2 (2020/01/10)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.9.1 (2019/12/23)

新機能

- Internet Explorer, Microsoft Edgeをサポートしました。
  - 詳細は [動作環境](https://docs.repro.io/ja/requirements.md) をご覧ください。



### 2.9.0 (2019/12/10)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.8.1 (2019/12/03)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.7.1 (2019/11/26)

修正

- 表示位置のタイプが「要素を指定して固定」または「埋め込み」を使用したメッセージを表示する際に、指定したDOM要素がページ内に存在しない場合でも配信数として計上されてしまうバグを修正しました。



### 2.7.0 (2019/11/26)

新機能

- 「カスタムHTMLメッセージ（ベータ版）」にフォーム系のHTML要素が使えるようになりました。



### 2.5.5 (2019/11/12)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.5.3 (2019/10/29)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.5.2 (2019/10/28)

新機能

- 吹き出しテンプレート(ベータ版)が利用できるようになりました。



### 2.5.0 (2019/10/09)

新機能

- メッセージの表示位置をサイト上のボタンや画像を指定して表示できる「メッセージ表示位置指定機能（ベータ版）」が利用できるようになりました。



### 2.4.7 (2019/09/05)

新機能

- イベントトリガー機能に正規表現を利用できるようになりました。

修正

- 同一ドメインの場合、メッセージのリンクを同一タブで表示されるように修正しました。



### 2.4.6 (2019/08/29)

新機能

- シルバーエッグレコメンドメッセージのためのユーザーIDを指定できる機能を実装をしました。



### 2.4.5 (2019/08/22)

修正

- コントロールグループのメッセージを表示後、特定の操作を行った場合にメッセージが正常に表示されなくなる問題を修正しました。



### 2.4.4 (2019/08/19)

修正

- コントロールグループのメッセージを表示後におけるトラッキングの精度を向上するための軽微な修正をしました。



### 2.4.3 (2019/08/15)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.4.2 (2019/08/09)

新機能

- 特定のグローバルIPでRepro Webを計測しない機能を実装しました。



### 2.4.1 (2019/08/08)

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 2.4.0 (2019/07/16)

新機能

- シルバーエッグレコメンドメッセージ機能(ベータ版)を実装しました。



### 2.3.0 (2019/07/12)

修正

- イベントトリガー機能に or 条件が設定できるように修正しました。
- トラッキングの精度を向上するための軽微な修正をしました。
- SDKの信頼性向上のための軽微な修正を行いました。



### 2.2.0 (2019/05/30)

新機能

- 配信前のWebメッセージを指定したサイトで確認することができるWebメッセージ・プレビュー機能を実装しました。



### 2.1.0 (2019/05/17)

新機能

- [オプトアウト機能](https://docs.repro.io/ja/dev/web/optout.md) を追加しました。イベントのトラッキングやメッセージを表示させたくない場合は、オプトアウトを設定してReproの機能を無効にすることができます。



### 2.0.0 (2019/04/25)

[バージョン1 から バージョン2 への更新手順](https://docs.repro.io/ja/dev/web/migration.md) をご確認いただきバージョン2にアップデートしてください。
数カ月後を目処にバージョン1は利用できなくなる予定です。

新機能

- [標準イベント](https://docs.repro.io/ja/dev/web/tracking.md#web-standard-event) ・ [標準ユーザープロフィール](https://docs.repro.io/ja/dev/web/user-profile.md#web-standard-user-profile)　を追加しました。

修正

- 保守性向上のためトラッキングコードを改善しました。



### 1.7.3 (2019/04/24)

修正

- パフォーマンスの向上のための修正をしました。



### 1.7.2 (2019/04/15)

修正

- トラッキングの精度を向上するための軽微な修正をしました。



### 1.7.1 (2019/04/11)

修正

- SDKの信頼性向上のための軽微な修正しました。



### 1.7.0 (2019/04/09)

新機能

- 同一画面内において複数のメッセージを同時に配信できるようになりました。
- あるイベントをトリガーとして表示するメッセージが2つ以上存在する場合に、表示するメッセージの優先度を制御できるようになりました。



### 1.6.1 (2019/04/04)

修正

- メッセージ内で表示する画像の読み込み処理が稀に失敗する現象を修正しました。
- SDKの信頼性向上のための軽微な修正を行いました。



### 1.6.0 (2019/03/20)

修正

- Cookieの読み書きを行う処理の安定性を向上させました。
- トラッキングルールを利用したイベントの収集に関連するバグを修正しました。
- SafariにおけるITP 2.1の影響を最小化する対策を行いました。
- SDKの信頼性向上のための軽微な修正を行いました。



### 1.5.0 (2019/03/12)

修正

- 初回セッションの判定に利用しているCookieのデータフォーマットを一部変更しました。
- Web SDKをロードするスニペットに async 属性を追加しました。
- SDKの信頼性向上のための軽微な修正を行いました。



### 1.4.1 (2019/02/22)

修正

- メッセージの表示に関するバグを修正しました。
- Web SDKを特定の読み込み順で動作させた際にユーザープロフィールが正常に設定されなくなるバグを修正しました。



### 1.4.1 (2019/02/18)

新機能

- メッセージのHTMLを自由に記述できる「カスタムHTMLメッセージ（ベータ版）」が利用できるようになりました。



### 1.3.0 (2019/02/14)

新機能

- Chrome, iOS Safari の対応バージョンを拡大しました。
  - 詳細は [動作環境](https://docs.repro.io/ja/requirements.md) をご覧ください。

修正

- SDKの信頼性向上のための軽微な修正を行いました。



### 1.0.1 (2018/12/18)

- これまでベータ版として提供していたWeb SDKをバージョン1として正式リリース。

---

## サポート期間

Web SDKについては、SDKの新しいメジャーバージョンがリリースされるタイミングで直前のメジャーバージョンのサポート期限が決まる方式をとります。

---

## FCMへの移行手順

* [Android](https://docs.repro.io/ja/releases/migration-to-fcm/android.md)
* [Unity](https://docs.repro.io/ja/releases/migration-to-fcm/unity.md)
* [Cordova](https://docs.repro.io/ja/releases/migration-to-fcm/cordova.md)
* [Monaca](https://docs.repro.io/ja/releases/migration-to-fcm/monaca.md)
* [Cocos2d-x](https://docs.repro.io/ja/releases/migration-to-fcm/cocos2d-x.md)

---

## FCMへの移行手順: Monaca

Googleからアナウンスされている通り、GCMは2019/4/11までに廃止が予定されております。すでにReproのプッシュ通知をGCMで実装している場合は、それまでに以下の手順を参照し、FCMでの実装に移行してください。

### 移行手順

#### Google Cloud PlatformのプロジェクトをFirebase Consoleへ移行する

Firebase ConsoleからGCMで利用していたプロジェクトを選択して作成してください：


* Google Cloud Platformのプロジェクト番号と、Firebase Consoleの送信者IDが同一であるか確認してください。Google Cloud Platformのプロジェクト番号は **Google Cloud Platform > IAMと管理 > 設定** のプロジェクト番号から確認できます：
  
* Firebase Consoleの送信者IDは **設定 > クラウドメッセージング** の送信者IDから確認できます：
  

#### FCMを設定する

1. [アプリの登録](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md#firebase-register-app) の手順を参照し、 `google-services.json` をダウンロードしてください。
2. [Firebaseの秘密鍵を生成](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md#firebase-generate-private-key) と [Firebaseの秘密鍵をReproに登録](https://docs.repro.io/ja/dev/sdk/push-notification/setup-android.md#firebase-register-private-key) の手順を参照し、Firebaseの秘密鍵をReproに登録してください。
3. [google-services.jsonファイルを追加する](https://docs.repro.io/ja/dev/sdk/push-notification/monaca.md#monaca-add-google-services-json) の手順を参照し、 `google-services.json` をプロジェクトに追加してください。

#### Repro Cordova Pluginのアップデート

Monaca IDEで **設定 > Cordovaプラグインの管理** をクリックします。



**Repro** にカーソルを合わせ、 **設定** をクリックします。



プラグインバージョン4.1.1以上を選択し、 **OK** をクリックします。

#### config.xmlファイルを編集する

`io.repro.android.GCMReceiver` を `io.repro.ReproReceiver` に修正してください：

```diff
 <receiver
-    android:name="io.repro.android.GCMReceiver"
+    android:name="io.repro.android.ReproReceiver"
     android:exported="true"
     android:permission="com.google.android.c2dm.permission.SEND">
     <intent-filter>
         <action android:name="com.google.android.c2dm.intent.RECEIVE" />
         <category android:name="YOUR_PACKAGE_NAME" />
     </intent-filter>
 </receiver>
```

#### Registration IDの取得方法を変更する

`Repro.enablePushNotification` もしくは `Repro.enablePushNotificationForAndroid` の呼び出しの引数を削除してください。

```diff
 function onDeviceReady() {
     ...
-    Repro.enablePushNotification(SENDER_ID);
-    Repro.enablePushNotificationForAndroid(SENDER_ID);
+    Repro.enablePushNotificationForAndroid();
```

---

## FAQ

* [App](https://docs.repro.io/ja/faq/app/index.md)
  * [SDK](https://docs.repro.io/ja/faq/app/index.md#sdk)
    * [端末の広告ID(IDFA, ADID)はどうすれば取得できますか？](https://docs.repro.io/ja/faq/app/sdk/1.md)
    * [セッションがアップロードされないケースは何がありますか？](https://docs.repro.io/ja/faq/app/sdk/2.md)
    * [アプリ内パラメーターの実装例を教えてください](https://docs.repro.io/ja/faq/app/sdk/3.md)
  * [プッシュ通知](https://docs.repro.io/ja/faq/app/index.md#id1)
    * [プッシュ通知が受信できないのですが、原因は何かありますか？](https://docs.repro.io/ja/faq/app/push/1.md)
    * [Reproからプッシュ通知を受信した際、デフォルトでバナー表示されますか？](https://docs.repro.io/ja/faq/app/push/2.md)
  * [イベントトラッキング](https://docs.repro.io/ja/faq/app/index.md#id2)
    * [イベントが上がってきません。何が原因ですか？](https://docs.repro.io/ja/faq/app/event-tracking/1.md)
    * [トラッキングされたイベントはどこで確認できますか？](https://docs.repro.io/ja/faq/app/event-tracking/2.md)
  * [ユーザープロフィール](https://docs.repro.io/ja/faq/app/index.md#id3)
    * [設定したユーザープロフィールはどこで確認できますか？](https://docs.repro.io/ja/faq/app/user-profile/1.md)
    * [ユーザープロフィールが登録されているか確認したい](https://docs.repro.io/ja/faq/app/user-profile/2.md)
  * [WebView](https://docs.repro.io/ja/faq/app/index.md#webview)
    * [Android 9 PieでHTTPページのWebviewのトラッキングができない](https://docs.repro.io/ja/faq/app/webview/1.md)
  * [その他](https://docs.repro.io/ja/faq/app/index.md#id4)
    * [AppleのApp Privacyに関する参考情報](https://docs.repro.io/ja/faq/app/app-privacy/1.md)
* [Web](https://docs.repro.io/ja/faq/web/index.md)
  * [Webメッセージ](https://docs.repro.io/ja/faq/web/index.md#id1)
    * [メッセージを表示したときにメッセージのサイズが意図通りならないのはなぜですか？](https://docs.repro.io/ja/faq/web/web-message/1.md)
    * [イベントトリガー、Webメッセージの表示条件における値の扱いについて](https://docs.repro.io/ja/faq/web/object-compare.md)
* [共通](https://docs.repro.io/ja/faq/general/index.md)
  * [アナリティクス](https://docs.repro.io/ja/faq/general/index.md#id2)
    * [アナリティクスに反映されるのはいつですか？](https://docs.repro.io/ja/faq/general/analytics/1.md)
  * [A/Bテスト 有意差表示](https://docs.repro.io/ja/faq/general/index.md#a-b)
    * [算出に利用している数値はどの時点で集計されたものですか？](https://docs.repro.io/ja/faq/general/significant-difference/1.md)
    * [「まだ有意差がありません」の表示から変わらないのですが、いつ頃終わるかの目安はありますか？](https://docs.repro.io/ja/faq/general/significant-difference/2.md)
    * [どの程度の配信数から結果の表示ができますか？](https://docs.repro.io/ja/faq/general/significant-difference/3.md)
    * [有意差とはなんですか？](https://docs.repro.io/ja/faq/general/significant-difference/4.md)
    * [信頼区間とはなんですか？](https://docs.repro.io/ja/faq/general/significant-difference/5.md)
    * [有意差ありとでたらそれ以降で判定結果は変わりませんか？](https://docs.repro.io/ja/faq/general/significant-difference/6.md)
    * [過去の有意差は見られますか？](https://docs.repro.io/ja/faq/general/significant-difference/7.md)
    * [信頼区間で用いている有意水準 (信頼水準) は変更できますか？](https://docs.repro.io/ja/faq/general/significant-difference/8.md)
  * [API](https://docs.repro.io/ja/faq/general/index.md#api)
    * [リクエスト実行状況を意識して、APIを利用する必要はありますか？](https://docs.repro.io/ja/faq/general/api/1.md)
  * [その他](https://docs.repro.io/ja/faq/general/index.md#id3)
    * [アプリ利用ユーザーへデータ取得の許諾を取る必要はありますか？](https://docs.repro.io/ja/faq/general/misc/2.md)
    * [Reproから来る通知メールをOFFにできますか？](https://docs.repro.io/ja/faq/general/misc/3.md)
    * [配信対象設定で利用できるマーケティング機能関連のイベントは何がありますか？](https://docs.repro.io/ja/faq/general/misc/4.md)

---

## App

### SDK

* [端末の広告ID(IDFA, ADID)はどうすれば取得できますか？](https://docs.repro.io/ja/faq/app/sdk/1.md)
* [セッションがアップロードされないケースは何がありますか？](https://docs.repro.io/ja/faq/app/sdk/2.md)
* [アプリ内パラメーターの実装例を教えてください](https://docs.repro.io/ja/faq/app/sdk/3.md)

### プッシュ通知

* [プッシュ通知が受信できないのですが、原因は何かありますか？](https://docs.repro.io/ja/faq/app/push/1.md)
* [Reproからプッシュ通知を受信した際、デフォルトでバナー表示されますか？](https://docs.repro.io/ja/faq/app/push/2.md)

### イベントトラッキング

* [イベントが上がってきません。何が原因ですか？](https://docs.repro.io/ja/faq/app/event-tracking/1.md)
* [トラッキングされたイベントはどこで確認できますか？](https://docs.repro.io/ja/faq/app/event-tracking/2.md)

### ユーザープロフィール

* [設定したユーザープロフィールはどこで確認できますか？](https://docs.repro.io/ja/faq/app/user-profile/1.md)
* [ユーザープロフィールが登録されているか確認したい](https://docs.repro.io/ja/faq/app/user-profile/2.md)

### WebView

* [Android 9 PieでHTTPページのWebviewのトラッキングができない](https://docs.repro.io/ja/faq/app/webview/1.md)

### その他

* [AppleのApp Privacyに関する参考情報](https://docs.repro.io/ja/faq/app/app-privacy/1.md)

---

## 端末の広告ID(IDFA, ADID)はどうすれば取得できますか？

### Android(ADID)

**「Google設定」アプリ > 「広告」** から確認することができます。

### iOS(IDFA: Identification For Advertisers)

以下のアプリをインストールすることで確認することができます。

[My Device ID by AppsFlyer](https://apps.apple.com/jp/app/my-device-id-by-appsflyer/id1192323960/)

[adjust Insights](https://apps.apple.com/jp/app/adjust-insights/id1125517808/)

---

## アプリ内パラメーターの実装例を教えてください

バナー枠の制御をアプリ内パラメーターで行う場合のサンプルコードを提示します。



使用するパラメーター

| パラメーター名 | 変数名 | パラメーター例 |
| --- | --- | --- |
| 表示フラグ | show_flag | true/false |
| バナー遷移先URL | banner_url | `https://example.com/campaign/springYYYYMMDD/` |
| 表示バナー画像URL | banner_img_url | `https://example.com/img/XXX.png` |

### 1. デフォルトパラメーターを設定する

[デフォルトのパラメーターを作成する](https://docs.repro.io/ja/dashboard/campaign/remote-config.md#remote-config-default-parameter) を参考に、デフォルトパラメーターを画像のように設定してください。



### 2. アプリ内パラメーターを使用するコードを記述する

バナー枠を表示したい場所に、アプリ内パラメーターを使って判定するコードを記述してください。

```objc
// Returns a Dictionary with key values
NSDictionary<NSString *, RPRRemoteConfigValue *> *values = [[Repro remoteConfig] allValues];
if (values[@"show_flag"] != nil && [values[@"show_flag"].stringValue isEqual: @"true"]) {
    // Write code using `values[@"banner_url"]` and `values[@"banner_img_url"]`
}
```

```swift
// Returns a Dictionary with key values
let values: Dictionary<String, RPRRemoteConfigValue> = Repro.remoteConfig.allValues()
if let value = values["show_flag"], value.stringValue == "true" {
    // Write code using `values["banner_url"]` and `values["banner_img_url"]`
}
```

```java
// Returns a Dictionary with key values
Map<String, RemoteConfigValue> values = Repro.getRemoteConfig().getAllValues();
if (values.get("show_flag") != null && values.get("show_flag").equals("true")) {
    // Write code using `values.get("banner_url")` and `values.get("banner_img_url")`
}
```

```kotlin
// Returns a Dictionary with key values
val values = Repro.getRemoteConfig().allValues
if (values["show_flag"] != null && values["show_flag"].toString() == "true") {
    // Write code using `values["banner_url"]` and `values["banner_img_url"]`
}
```

```cpp
// Returns a Map with all values.
std::map<std::string, RemoteConfigValue*> values = ReproCpp::getRemoteConfig().getAllValues();
if (values["show_flag"] != nullptr && values["show_flag"] == "true") {
    // Write code using `values["banner_url"]` and `values["banner_img_url"]`
}
```

```csharp
// Returns a Dictionary with all values.
Dictionary<string, RemoteConfigValue> values = Repro.RemoteConfig.GetAllValues();
if (values["show_flag"] != null && values["show_flag"] == "true") {
    // Write code using `values["banner_url"]` and `values["banner_img_url"]`
}
```

```js-cordova
// Returns an associative array with all values.
Repro.remoteConfig.getAllValues(
    function(values) {
        if (values["show_flag"] != null && values["show_flag"] == "true") {
            // Write code using `values["banner_url"]` and `values["banner_img_url"]`
        }
    }
);
```

```js-react-native
// Returns an associative array with all values.
Repro.remoteConfig.getAllValues((values) => {
    if (values["show_flag"] != null && values["show_flag"] == "true") {
        // Write code using `values["banner_url"]` and `values["banner_img_url"]`
    }
});
```

```dart
// Returns a Map with all values.
var values = await Repro.remoteConfig.getAllValues();
if (values["show_flag"] != null && values["show_flag"].toString() == "true") {
    // Write code using `values["banner_url"]` and `values["banner_img_url"]`
}
```

### 3. キャンペーンを作成する

[キャンペーンを作成する](https://docs.repro.io/ja/dashboard/campaign/remote-config.md#remote-config-campaign) を参考に、バナーを表示したいユーザーに配信されるようキャンペーンを作成してください



### アプリ起動直後に表示される画面でアプリ内パラメーターを参照したい場合

アプリ起動直後に表示される画面で、ユーザーごとに表示を切り替えるためにアプリ内パラメーターを使用したい場合、 Repro の `setup` が完了するまでアプリ内パラメーターの最新の値は反映されません。
その場合、 `fetch` をご利用いただくことで、 `setup` の完了を待ってからアプリ内パラメーターの値を使用することが可能です。
`setup` より前に `fetch` のコールバック関数を定義し、その中で値を取得した後の処理を記述してください。

以下にコード例を提示します。

```objc
[[Repro remoteConfig] fetchWithTimeout:0 completionHandler:^(RPRRemoteConfigFetchStatus fetchStatus) {
    if (fetchStatus == RPRRemoteConfigFetchStatusSuccess) {
        [[Repro remoteConfig] activateFetched];
        NSDictionary<NSString *, RPRRemoteConfigValue *> *values = [[Repro remoteConfig] allValues];
        if (values["show_flag"] != null && values["show_flag"].toString() == "true") {
            // Write code using `values["banner_url"]` and `values["banner_img_url"]`
        }
    }
}];

[Repro setup:@"YOUR_APP_TOKEN"];
```

```swift
Repro.remoteConfig.fetch(withTimeout: 0) { status in
    if status == .success {
        Repro.remoteConfig.activateFetched()
        let values: Dictionary<String, RPRRemoteConfigValue> = Repro.remoteConfig.allValues()
        if let value = values["show_flag"], value.stringValue == "true" {
            // Write code using `values["banner_url"]` and `values["banner_img_url"]`
        }
    }
}

Repro.setup(token: "YOUR_APP_TOKEN")
```

```java
Repro.getRemoteConfig().fetch(0, new RemoteConfigListener() {
    @Override
    public void onCompletion(FetchStatus status) {
        if (status == FetchStatus.SUCCESS) {
            Repro.getRemoteConfig().activateFetched();
            Map<String, RemoteConfigValue> values = Repro.getRemoteConfig().getAllValues();
            if (values.get("show_flag") != null && values.get("show_flag").equals("true")) {
                // Write code using `values.get("banner_url")` and `values.get("banner_img_url")`
            }
        }
    }
});

Repro.setup(this, YOUR_APP_TOKEN);
```

```kotlin
Repro.getRemoteConfig().fetch(0) { status ->
    if (status == FetchStatus.SUCCESS) {
        Repro.getRemoteConfig().activateFetched()
        val values = Repro.getRemoteConfig().allValues
        if (values["show_flag"] != null && values["show_flag"].toString() == "true") {
            // Write code using `values["banner_url"]` and `values["banner_img_url"]`
        }
    }
}

Repro.setup(this, YOUR_APP_TOKEN)
```

```cpp
ReproCpp::getRemoteConfig().fetch(0, [](ReproCpp::RemoteConfig::FetchStatus status) {
    if (status == ReproCpp::RemoteConfig::FetchStatusSuccess) {
        ReproCpp::getRemoteConfig().activateFetched();
        std::map<std::string, RemoteConfigValue*> values = ReproCpp::getRemoteConfig().getAllValues();
        if (values["show_flag"] != nullptr && values["show_flag"] == "true") {
            // Write code using `values["banner_url"]` and `values["banner_img_url"]`
        }
    }
});
```

```csharp
Repro.RemoteConfig.Fetch(0, (status) =>
{
    if (status == Repro.FetchStatus.Success)
    {
        Repro.RemoteConfig.ActivateFetched();
        Dictionary<string, RemoteConfigValue> values = Repro.RemoteConfig.GetAllValues();
        if (values["show_flag"] != null && values["show_flag"] == "true")
        {
            // Write code using `values["banner_url"]` and `values["banner_img_url"]`
        }
    }
});
```

```js-cordova
Repro.remoteConfig.fetch(0, function(status) {
    // success callback
    if (status == Repro.remoteConfig.FetchStatus.Success) {
        Repro.remoteConfig.activateFetched(function(message) {
            // success callback
            Repro.remoteConfig.getAllValues(
                function(values) {
                    if (values["show_flag"] != null && values["show_flag"] == "true") {
                        // Write code using `values["banner_url"]` and `values["banner_img_url"]`
                    }
                }
            );
        }, function(message) {
            // error callback
        });
    }
}, function(status) {
    // error callback
});
```

```js-react-native
Repro.remoteConfig.fetch(0, (status) => {
    if (status == Repro.remoteConfig.FETCH_STATUS.REMOTE_CONFIG_SUCCESS) {
        Repro.remoteConfig.activateFetched();
        Repro.remoteConfig.getAllValues((values) => {
            if (values["show_flag"] != null && values["show_flag"] == "true") {
                // Write code using `values["banner_url"]` and `values["banner_img_url"]`
            }
        });
    } else if (status == Repro.remoteConfig.FETCH_STATUS.REMOTE_CONFIG_TIMEOUT_REACHED) {
    } else if (status == Repro.remoteConfig.FETCH_STATUS.REMOTE_CONFIG_ALREADY_FETCHED) {
    }
});
```

```dart
await Repro.remoteConfig.fetch(0, (result) {
    if (result == FetchStatus.success) {
        await Repro.remoteConfig.activateFetched();
        var values = await Repro.remoteConfig.getAllValues();
        if (values["show_flag"] != null && values["show_flag"].toString() == "true") {
            // Write code using `values["banner_url"]` and `values["banner_img_url"]`
        }
    }
});
```

---

## トラッキングされたイベントはどこで確認できますか？

トラッキングされたイベントは以下の2つの方法で確認ができます。

- イベント設定画面でイベントが反映されているか確認する
- オーディエンス機能でユーザー単位のイベント実行を確認する

### イベント設定画面でイベントが反映されているか確認する

**イベント > イベント設定** で確認できます。



一度でもトラッキングされたことがあるイベントはイベント設定画面に反映されます。

##### NOTE
- イベント設定数の上限を超えてトラッキングされたイベントは反映されません。
- 上限を超えてイベントを利用したい場合は弊社のカスタマーサクセス担当、もしくはRepro管理画面の右下にあるアイコンよりチャットサポートへお問い合わせください。

イベント設定の詳細についてはサポートサイトの [イベント設定を利用する](https://support.repro.io/hc/ja/articles/23338779554457) をご覧ください。

### オーディエンス機能でユーザー単位のイベント実行を確認する

[オーディエンス](https://docs.repro.io/ja/dashboard/campaign/audience.md) のID指定（ID指定オーディエンス）を利用することで、ユーザー単位でトラッキングされたイベントの実行回数を確認できます。
ID指定オーディエンスへのユーザーの追加はユーザーID、もしくはデバイスIDを利用する方法とQRコードを利用する方法があります。

##### NOTE
- アプリの構成によっては運用ご担当者様がユーザーID、もしくはデバイスIDの確認が難しい場合があります。
- [QRコードを用いてオーディエンスにユーザーを登録する](https://docs.repro.io/ja/dev/sdk/qr-code.md) を参考に実装することで、ユーザーID、もしくはデバイスIDがわからなくてもQRコードを利用したID指定オーディエンスへのユーザーの追加ができますので実装することをお勧めします。

ID指定オーディエンスの詳細については [新規作成: ID指定](https://docs.repro.io/ja/dashboard/campaign/audience.md#create-specified-id) をご確認ください。

---

## 設定したユーザープロフィールはどこで確認できますか？

**設定 > ユーザープロフィール設定** で確認できます。

---

## AppleのApp Privacyに関する参考情報

本コンテンツでは、App Storeに新しく追加された「App Privacy」に回答するための参考情報を提供します。
なお、弊社では本コンテンツを利用することによる App Store への **アプリ申請時のリジェクトについては責任を負いかねます。** ご了承ください。

### モバイルアプリ向けRepro SDKが取得している情報について

Repro SDKが取得している情報は、[利用規約](https://repro.io/company/legal/term/) の第6条に記載されている以下になります。

#### 必ず取得している情報

- アプリ情報（バージョン、アプリ名（iOS: bundle id 、 Android: パッケージ名））
- デバイス ID（iOS:IDFV 、Android:ANDROID_ID（オプトアウト可））
- 端末情報（機種情報、OS 種類情報、OS バージョン情報等）

#### 任意で取得している情報

- イベント情報
- アプリ操作情報（動画、タップ操作等）
- ユーザープロフィール情報
- プッシュ通知デバイストークン
- 広告 ID (iOS: IDFA、Android: AAID)
- ネットワークタイプ

### それぞれの情報が、どのような目的・用途で取得されているのか

#### アプリ情報（バージョン、アプリ名（iOS: bundle id 、 Android: パッケージ名））

Repro SDKの利用状況の分析・改善のために取得されています。
本情報を、Reproの管理画面上から利用することはできず、マーケティング施策のために利用することはできません。

#### デバイス ID（iOS:IDFV 、Android:ANDROID_ID（オプトアウト可））

弊社が定義する [ユーザーID](https://docs.repro.io/ja/dev/sdk/user-id.html) を設定しない場合、デバイスIDがユーザーの識別子として利用されます。その場合は1ユーザー = 1端末となります。
ユーザーの定義に関しては [こちら](https://docs.repro.io/ja/dashboard/misc/user-definition.html) をご覧ください。
他にも、[オーディエンス](https://docs.repro.io/ja/dashboard/campaign/audience.html) 画面におけるID指定時の登録識別子として利用されています。
本情報を、プッシュ通知やアプリ内メッセージのマーケティング施策のために利用することはできません。

#### 端末情報（機種情報、OS 種類情報、OS バージョン情報等）

Repro管理画面上での分析機能のために取得されています。
本情報を、プッシュ通知やアプリ内メッセージのようなマーケティング施策のために利用することはできません。

#### イベント情報

Repro管理画面より、プッシュ通知やアプリ内メッセージのようなマーケティング施策を利用するために必要な情報です。
また、分析機能のためにも利用されます。
Reproが自動で取得するイベントのうち、マーケティング施策や分析機能の用途で利用できるイベントは以下のみとなります。

- アプリ起動
- 初回起動

上記以外のイベントの取得については、アプリ事業者様にて任意で設定し取得するものとなります。

#### アプリ操作情報（動画、タップ操作等）

既に廃止された機能のための情報であり、本項目の情報の取得自体行っていません。

#### ユーザープロフィール情報

Repro管理画面より、プッシュ通知やアプリ内メッセージのようなマーケティング施策を利用するために必要な情報です。
また、分析機能のためにも利用されます。
Reproが自動で取得するユーザープロフィールのうち、マーケティング施策や分析機能の用途で利用できるものは以下のみとなります。

- 最後に使った日
- ロケール
- タイムゾーン

詳細は [こちら](https://docs.repro.io/ja/dev/sdk/user-profile.html#id4) をご確認ください。
上記以外のユーザープロフィールの取得については、アプリ事業者様にて任意で設定し取得するものとなります。

#### プッシュ通知デバイストークン

エンドユーザーの端末にRepro 管理画面よりプッシュ通知施策を実施するために必要な情報です。

#### 広告 ID (iOS: IDFA、Android: AAID)

Reproの [オーディエンス](https://docs.repro.io/ja/dashboard/campaign/audience.html) 画面におけるID指定時の登録識別子として利用されています。

本情報は、アプリ側の実装により取得しないようにすることも可能です。
詳細については、[こちら](https://reproio.zendesk.com/hc/ja/articles/900004746846-%E7%AB%AF%E6%9C%AB%E3%81%AE%E5%BA%83%E5%91%8AID-IDFA-ADID-%E3%81%AF%E3%81%A9%E3%81%86%E3%81%99%E3%82%8C%E3%81%B0%E5%8F%96%E5%BE%97%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%81%8B-) をご確認ください。

#### ネットワークタイプ

既に廃止された機能のための情報であり、現在この情報は利用されていません。
また、Repro iOS SDK 5.1.0 以上をご利用の場合は、本項目の情報の取得自体行っていません。

### 上記の情報と収集されるデータイプとの関係

#### Contact Info / 連絡先情報

| データタイプ | SDKで自動取得 | 備考 |
| --- | --- | --- |
| 名前 | Optional | アプリ内で実装を行った場合のみ取得します |
| メールアドレス | Optional | アプリ内で実装を行った場合のみ取得します |
| 電話番号 | Optional | アプリ内で実装を行った場合のみ取得します。 |
| 住所 | Optional | アプリ内で実装を行った場合のみ取得します。 |
| その他のユーザー連絡先情報 | Optional | アプリ内で実装を行った場合のみ取得します。 |

#### Health and Fitness / 健康とフィットネス

| データタイプ | SDKで自動取得 | 備考 |
| --- | --- | --- |
| 健康 | NO |  |
| フィットネス | NO |  |

#### Financial Info / 財務情報

| データタイプ | SDKで自動取得 | 備考 |
| --- | --- | --- |
| お支払い情報 | NO |  |
| クレジット情報 | NO |  |
| その他の財務情報 | NO |  |

#### Location / 位置情報

| データタイプ | SDKで自動取得 | 備考 |
| --- | --- | --- |
| 正確な位置 | Optional | アプリ内で実装を行った場合のみ取得します。 |
| 大体の位置 | Optional | アプリ内で実装を行った場合のみ取得します。 |

#### Sensitive Info / 機密情報

| データタイプ | SDKで自動取得 | 備考 |
| --- | --- | --- |
| 機密情報 | NO |  |

#### Contacts / 連絡先

| データタイプ | SDKで自動取得 | 備考 |
| --- | --- | --- |
| 連絡先 | NO |  |

#### User Content / ユーザーコンテンツ

| データタイプ | SDKで自動取得 | 備考 |
| --- | --- | --- |
| メールまたはテキストメッセージ | NO |  |
| 写真または動画 | NO |  |
| 音声データ | NO |  |
| ゲームプレイコンテンツ | NO |  |
| カスタマーサポート | NO |  |
| その他のユーザーコンテンツ | NO |  |

#### Browsing History / 閲覧履歴

| データタイプ | SDKで自動取得 | 備考 |
| --- | --- | --- |
| 閲覧履歴 | NO |  |

#### Search History / 検索履歴

| データタイプ | SDKで自動取得 | 備考 |
| --- | --- | --- |
| 検索履歴 | NO |  |

#### Identifiers / 識別情報

| データタイプ | SDKで自動取得 | 備考 |
| --- | --- | --- |
| ユーザーID | Optional | userIdを設定する実装を行った場合にのみ取得します。 |
| デバイスID (IDFA) | YES |  |

#### Purchases / 購入

| データタイプ | SDKで自動取得 | 備考 |
| --- | --- | --- |
| 購入履歴 | Optional | アプリ内で実装を行った場合のみ取得を行います。 |

#### Usage Data / データ使用状況

| データタイプ | SDKで自動取得 | 備考 |
| --- | --- | --- |
| 製品インタラクション | YES | アプリ起動・初回起動に関しては自動的に取得を行います。 |
| 広告データ | Optional | アプリ内で実装を行った場合のみ取得を行います |
| その他の使用状況データ | Optional | アプリ内で実装を行った場合のみ取得を行います |

#### Diagnostics / 診断データ

| データタイプ | SDKで自動取得 | 備考 |
| --- | --- | --- |
| クラッシュデータ | NO |  |
| パフォーマンスデータ | NO |  |
| その他の診断データ | NO |  |

#### Other Data / その他のデータ

| データタイプ | SDKで自動取得 | 備考 |
| --- | --- | --- |
| その他のデータタイプ | YES | アプリ情報（バージョン、アプリ名（iOS: bundle id 、 Android: パッケージ名）/ 端末情報（機種情報、OS 種類情報、OS バージョン情報等) / ユーザープロフィール(最後に使った日、ロケール、タイムゾーン) を自動的に取得しています。 |

---

## Web

### Webメッセージ

* [メッセージを表示したときにメッセージのサイズが意図通りならないのはなぜですか？](https://docs.repro.io/ja/faq/web/web-message/1.md)
* [イベントトリガー、Webメッセージの表示条件における値の扱いについて](https://docs.repro.io/ja/faq/web/object-compare.md)

---

## メッセージを表示したときにメッセージのサイズが意図通りならないのはなぜですか？

サイトのソースコード上で `viewport` の 指定があると、いずれのメッセージテンプレートにおいても意図通りに表示されない可能性があります。
 
意図通りに表示されない場合は、 `viewport` の指定を削除するか、カスタムメッセージをご利用いただく必要があります。
 
 
ご不明点がございましたら、チャットサポートまでご連絡ください。
