Advertisement
Guest User

Untitled

a guest
Jan 23rd, 2019
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.63 KB | None | 0 0
  1. # [Table of Contents](#table-of-contents)
  2. *Note the sections 1,2,3, 4 are applicable for both wappier solutions*
  3. 1. [Overview](#overview)
  4. 2. [Set Up in 3 Steps!](#set-up-in-3-steps)
  5. 1. [Import Libraries](#import-libraries)
  6. 2. [Update Android Manifest](#update-android-manifest)
  7. 3. [Initialize SDK](#initialize-sdk)
  8. 3. [Tracking Events](#tracking-events)
  9. 1. [Tracking Custom In-App Actions](#tracking-custom-actions)
  10. 2. [Tracking Purchase Events](#tracking-purchase-events)
  11. 4. [Tracking User Profile Details](#tracking-userDetails)
  12. 1. [Tracking User Profile attributes](#tracking-userProfileAttributes)
  13. 2. [Adding or Removing tags to a User](#tracking-tags)
  14. 3. [Adding or Removing Key-Value pairs to a User](#tracking-kvp)
  15. 4. [Getting Control/Target Group Status](#tracking-controlTargetGroupStatus)
  16. 5. [Loyalty Icon & Profile Customization](#loyalty-icon-profile-customization)
  17. *Note: this section is applicable for Loyalty & Retention solution*
  18. 1. [Loyalty Icon Set up and Position](#loyalty-icon-set-up-and-position)
  19. 2. [Showing Loyalty User Profile](#showing-loyalty-user-profile)
  20. 3. [Loyalty Profile Orientation](#loyalty-profile-orientation)
  21. 4. [Setting a username for the user](#setting-up-username-for-user)
  22.  
  23. 6. [In-app Products Setup & Redemption Flow](#in-app-products-setup-redemption-flow)
  24. *Note: this section is applicable for Loyalty & Retention solution*
  25.  
  26. 7. [Regional Pricing using Control Group](#regional-pricing-using-control-group)
  27. *Note: this section is applicable for Regional Pricing solution*
  28.  
  29.  
  30.  
  31.  
  32. ## **OVERVIEW** (for both wappier solutions)<a name="overview"></a>
  33.  
  34. The **wappier Loyalty SDK** consists of a core library which enables tracking of in-game actions.
  35.  
  36. Here's how it works:
  37.  
  38. * Events are recorded each time an action is performed (e.g. the *INAPP_ACTION* event), every time the user launches the game (e.g. the *OPEN* event) and the first time the game runs on the user’s device (e.g. the *FIRST_RUN* event).
  39.  
  40. * Then, they are processed in real time by wappier’s **Revenue Management Platform** and **Machine Learning Technology** in order for the user to be rewarded with the corresponding reward.
  41.  
  42. Here are some of the events required to be tracked from your game and used by wappier’s Machine Learning Technology to optimize Loyalty’s performance in your game:
  43.  
  44. |**Event Name**|**Type**|**Recorded when**|
  45. |---|---|---|
  46. |FIRST_RUN|Unique|User installs the game for the first time|
  47. |OPEN|Repetitive|User launches the game|
  48. |TIME_SPENT|Repetitive|User exits from the game
  49. |PURCHASE|Repetitive|User buys an in-app product
  50. |CUSTOM_EVENT_NAME|Unique or Repetitive|Depending on the game, a variety of actions can be tracked and incentivized.  Some event examples: *TUTORIAL_COMPLETE, LEVEL_COMPLETE, HIGHSCORE, HERO_LEVEL_5*
  51.  
  52. ![Image URL not working properly](https://s3.amazonaws.com/wizzogames-live/marketing_content/kb_wappiermachine.png)
  53. *How user data are tracked and processed real time by wappier’s Revenue Management Platform and Machine Learning Technology in order for the user to be rewarded with a Personalized Rewarding Loyalty Scheme.*
  54.  
  55. **Requirements before Set Up**
  56. We will provide you with an API key that you’ll need to add in your game during the integration in order for the SDK to communicate with our Revenue Management Platform.
  57.  
  58. The **wappier Optimization SDK** needs *Android SDK 16 (4.1)* or later versions to work properly.
  59.  
  60.  
  61. ## **SET UP IN 3 STEPS!** (for both wappier solutions)<a name="set-up-in-3-steps"></a>
  62.  
  63. Below you will find the required steps to integrate the **wappier Optimization SDK** with your game:
  64.  
  65. #### **Step 1 – Import Libraries**<a name="import-libraries"></a>
  66.  
  67. For **wappier Libraries**, copy *WappierSDK-x.y.z-liveRelease.aar* file at the libs folder and add it to project build path.
  68.  
  69. If *ProGuard* is enabled, the following rules should be added to ProGuard rules:
  70. ```
  71. -keep public class com.wappier.** { *; }
  72. ```
  73.  
  74. For **Google Libraries**, add the following dependency to app/build.gradle file:
  75. ```gradle
  76. compile 'com.google.android.gms:play-services-basement:12.0.1'
  77. ```
  78.  
  79. Please note that the minimum version of Google Play base library that is supported by the **wappier Optimization SDK** is version 9.8.1 and the maximum one is 12.0.1. If you need to include another base version, please add the below dependency instead:
  80. ```gradle
  81. compile 'com.google.android.gms:play-services-ads:15.0.1'
  82. ```
  83.  
  84. Additional dependencies:
  85. ```gradle
  86. compile 'com.android.support.constraint:constraint-layout:1.1.0'
  87. compile 'com.android.support:design:X+'
  88. compile 'com.android.support:cardview-v7:X+'
  89. compile 'com.android.support:recyclerview-v7:X+'
  90. ```
  91. where X is the compileSDKVersion that the game supports.
  92.  
  93. #### **Step 2 – Update AndroidManifest.xml**<a name="update-android-manifest"></a>
  94. Add the following declaration to the *AndroidManifest.xml* inside the tag for debugging purposes:
  95. ```xml
  96. <meta-data android:name="wappier_debug" android:value="true"/>
  97. ```
  98. The wappier_debug boolean value enables logging messages.
  99.  
  100. Add the following permissions to the *AndroidManifest.xml*:
  101. ```java
  102. <uses-permission android:name="android.permission.INTERNET"/>
  103. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
  104. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
  105. <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> // this permission is optional
  106. ```
  107.  
  108. The **wappier Optimization SDK** is using the *android.permission.ACCESS_FINE_LOCATION* permission to determine the device location in order to serve region-specific content and features accurately.
  109.  
  110. For this reason, apps targeting Android Marshmallow (API 23) and later should prompt users to grant it at runtime instead of install time. Since users can revoke permissions at any time from the app Settings screen, your app needs to check that it has the permissions it needs every time it runs. For more details on how to achieve this, please follow [this link](https://developer.android.com/training/permissions/index.html).
  111.  
  112. If you do not handle *android.permission.ACCESS_FINE_LOCATION* permission for API > 23, SDK should be functional but location would not be accurate.
  113.  
  114.  
  115. #### **Step 3 – Initialize SDK**<a name="initialize-sdk"></a>
  116. To initiate the **wappier Optimization SDK**, create a new Application class or update the existing one and add the following line at the *onCreate()* method of that class:
  117. ```java
  118. Wappier.getInstance()
  119. .startSession(this,YOUR_APPLICATION_KEY)
  120. .setUserName(your_unique_user_identifier);
  121. ```
  122.  
  123. ## **Tracking Events** (for both wappier solutions)<a name="tracking-events"></a>
  124. The steps below provide instructions for tracking in-game events. FIRST_RUN, OPEN and TIME_SPENT events are tracked automatically.
  125.  
  126. #### **Tracking Custom In-App Actions**<a name="tracking-custom-actions"></a>
  127. The steps below provide instructions for tracking in-game events. FIRST_RUN, OPEN and TIME_SPENT events are tracked automatically.
  128.  
  129. #### **Tracking Custom In-App Actions**
  130. To track in-game actions add the following line:
  131. ```java
  132. Wappier.getInstance().trackAction("YOUR_CUSTOM_EVENT_NAME");
  133. ```
  134.  
  135. YOUR\_CUSTOM\_EVENT\_NAME can have any custom value including the following special characters:
  136. *0-9, A-Z, a-z, \# $ % = @ ! { } ( ) \[ ] < > \` ~ & ? . : ; \_ | ^ + \- *
  137.  
  138. These actions are directly correlated with the gameplay style of each game and they are the main source of points for the user. Here you may find some common examples of tracked actions:
  139.  
  140. |Event Name|Occurrence|Tracked when|
  141. |---|---|
  142. |TUTORIAL_COMPLETE|Unique|User finishes the last objective of the tutorial flow|
  143. |LEVEL_COMPLETE|Repetitive|User completes a level or stage in the game|
  144. |BATTLE_WON|Repetitive|Win a match versus A.I.|
  145. |HIGHSCORE|Repetitive|User completes an already finished level or stage with higher score|
  146. |ACHIEVEMENT|Repetitive|User earns an in-game achievement|
  147. |HERO_LVL_5|Unique|Hero reached level 5|
  148. |CASTLE_LVL_7|Unique|Main building was upgraded to level 7|
  149. |FIRST_PURCHASE|Unique|User completes his first transaction|
  150. |50_ONLINE_BATTLES|Unique|Win 50 battles versus real opponents|
  151.  
  152. #### **Tracking Purchase Events**<a name="tracking-purchase-events"></a>
  153. In order to track in-app purchases performed in your game, add the following line:
  154. ```
  155. Wappier.getInstance().trackPurchase(
  156. revenue,
  157. "currencyCode",
  158. "googleOrderId",
  159. "productId",
  160. "purchaseToken"
  161. );
  162. ```
  163.  
  164. Mandatory Fields:
  165.  
  166. |Value|Type|Description|Example|
  167. |---|---|---|---|
  168. |revenue|Double|Total numeric amount for the purchase|19.99|
  169. |"currencyCode"|Char|The local currency code of the transaction|SAR|
  170. |"googleOrderId"|Char|The GPA-formatted order ID of the transaction|GPA-1234.1234.1234.12345|
  171. |"productId"|Char|The product identifier of the in app product|diamonds.king.001|
  172. |"purchaseToken"|Char|A token that uniquely identifies a purchase for a given item and user pair|This alphanumeric string is 150-200 characters long|
  173.  
  174. The following code snippet suggests a way to track a purchase event:
  175. ```
  176. // Callback for when a purchase is finished
  177. IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
  178. if (purchase.getSku().equals(..SKU id..)) {
  179. Wappier.getInstance().trackPurchase(
  180. 1.80,
  181. "EUR",
  182. purchase.getOrderId(),
  183. purchase.getSku(),
  184. purchase.getToken()
  185. );
  186. }
  187. };
  188. ```
  189.  
  190. ## **TRACKING USER DETAILS** (for both wappier solutions)<a name="tracking-userDetails"></a>
  191.  
  192. #### **Tracking User Profile attributes** <a name="tracking-userProfileAttributes"></a>
  193.  
  194. To track user profile attributes add the following code:
  195.  
  196. ```java
  197. HashMap<String, String> attributesMap = new HashMap<>();
  198. attributesMap.put("userAvatarURL", "avatar.jpeg");
  199. attributesMap.put("profileName","Bob");
  200. attributesMap.put("email", "bob@mail.com");
  201. attributesMap.put("phoneNumber", "555-3982");
  202. attributesMap.put("country", "US");
  203. Wappier.getInstance().trackUserProfile(attributesMap);
  204. ```
  205. You can use any number of attribute keys and values. User Profile attributes will be associated with the user document.
  206.  
  207. #### **Adding or Removing tags to a User** <a name="tracking-tags"></a>
  208.  
  209. To add or remove tags to a user, add the following code:
  210. ```java
  211. Wappier.getInstance().addTag("addTag");
  212. ```
  213. ```java
  214. Wappier.getInstance().removeTag("removeTag");
  215. ```
  216. You can use any string as a tag. Tags are associated with the user document and can be used for segmentation, targeting and analytics.
  217.  
  218. #### **Adding or Removing Key-Value pairs to a User** <a name="tracking-kvp"></a>
  219.  
  220. To add or remove one or multiple Key-Value pair(s) to a user add the following code:
  221.  
  222. ```java
  223. Wappier.getInstance().trackKVP("KvpKey","KvpValue");
  224. ```
  225.  
  226. ```java
  227. HashMap<String, String> KvpHash=new HashMap<>();
  228. KvpHash.put("key1","kvpValue1");
  229. KvpHash.put("key2","kvpValue2");
  230. KvpHash.put("key3","kvpValue3");
  231. Wappier.getInstance().trackKVP(KvpHash);
  232. ```
  233.  
  234.  
  235. #### **Getting Control/Target Group Status** <a name="tracking-controlTargetGroupStatus"></a>
  236. ```java
  237. boolean controlGroupFlag = Wappier.getInstance().isUserInControlGroup();
  238. ```
  239.  
  240.  
  241. ## **LOYALTY ICON & PROFILE CUSTOMIZATION** (for Loyalty & Retention solution)<a name="loyalty-icon-profile-customization"></a>
  242. The below options can be used to handle the Loyalty Icon and User Profile in your game.
  243.  
  244. #### **Loyalty Icon Set up and Position**<a name="loyalty-icon-set-up-and-position"></a>
  245. You can add the Loyalty Icon programmatically or with xml in your layout. When the user taps on this icon, his Loyalty Profile card is shown.
  246. ```
  247. // Programmatically
  248. WappierButton mCustomButton= new WappierButton();
  249.  
  250. // Xml
  251. <wappier.sdk.wappier.com.loyalty.ui.WappierButton
  252. android:id=”@+id/wappier_button”
  253. android:layout_width=”50dp”
  254. android:layout_height=”50dp”
  255. android:layout_alignParentBottom=”true”
  256. android:layout_alignParentEnd=”true”
  257. android:layout_alignParentRight=”true” />
  258. ```
  259.  
  260. To present or hide the Loyalty Icon at any given time, use one of the following lines:
  261. ```
  262. mCustomButton.showLoyIcon("REFERRER");
  263. ```
  264. ```
  265. mCustomButton.hideLoyIcon();
  266. ```
  267. where "REFERRER" is a free text parameter describing the screen that the Icon has shown.
  268.  
  269. To set the Loyalty Icon position at any given in-game screen, use one of the following lines:
  270. ```
  271. mCustomButtom.setPosition(200,200) // setPosition(xPoint,yPoint)
  272. ```
  273. ```
  274. mCustomButton.setPosition(Position.Top,Position.Left)
  275. ```
  276. ```
  277. mCustomButton.setPosition(10,Position.Top,Position.Left)
  278. ```
  279.  
  280. One of the below constants can also be used in order to set the Loyalty Icon position:
  281.  
  282. |Constant|Position|
  283. |---|---|
  284. |Position.DEFAULT||Icon displays default position|
  285. |Position.LEFT||Icon displays at left of the screen|
  286. |Position.Right|Icon displays at right of the scree|
  287. |Position.Top|Icon displays at top of the screen|
  288. |Position.Bottom|Icon displays at bottom of the screen|
  289.  
  290. #### **Showing Loyalty User Profile**<a name="showing-loyalty-user-profile"></a>
  291. To present the Loyalty User Profile manually without him tapping on the Loyalty Icon, add the following line:
  292. ```
  293. mCustomButton.showLoy();
  294. ```
  295.  
  296. #### **Loyalty Profile Orientation**<a name="loyalty-profile-orientation"></a>
  297. You can control the orientation of the Loyalty Profile depending on the orientation that your game supports:
  298. ```
  299. Wappier.getInstance()
  300. .startSession(this, Env.APP_KEY)
  301. .setLOYOrientation(PREFERRED_ORIENTATION);
  302. ```
  303. "PREFERRED\_ORIENTATION" can take one of the following constants:
  304.  
  305. |Constant|Result|
  306. |---|---|
  307. |Orientation.PORTRAIT|Lock orientation to portrait|
  308. |Orientation.LANDSCAPE|Lock orientation to landscape|
  309. |Orientation.OPEN|Loyalty card will rotate depending on device orientation|
  310.  
  311. #### **Setting a username for the user**<a name="setting-up-username-for-user"></a>
  312. You can link multiple devices to a single account by setting the username on session start request.
  313. ```
  314. Wappier.getInstance()
  315. .startSession(this, Env.APP_KEY)
  316. .setUserName(your_unique_user_identifier);
  317. ```
  318.  
  319.  
  320. ## **IN-APP PRODUCTS SETUP & REDEMPTION FLOW** (for Loyalty & Retention solution)<a name="in-app-products-setup-redemption-flow"></a>
  321. In order to include your in-app products in the Loyalty Reward Scheme, each of the items have to be matched with a unique, custom name. When the user tries to spend points to redeem an item, the SDK should be informed if that redemption is successful in order to subtract the respective points from the user's Loyalty Profile.
  322.  
  323. To receive redemption notifications, use one of the following code snippets in your activity:
  324. ```
  325. Wappier.registerRedeemCallback(new RedeemListener() {
  326. @Override
  327. public void redeemCallback(String sku, final String redemptionId, int quantity) {
  328. }
  329. });
  330. ```
  331. ```
  332. RedeemListener redeemListener = new RedeemListener() {
  333. @Override
  334. public void redeemCallback(final String sku, final String redemptionId, final int quantity) {
  335. final Handler handler = new Handler();
  336. handler.postDelayed(new Runnable() {
  337. @Override
  338. public void run() {
  339. if (sku.equals("SKU1") || sku.contains("test_sku_")) {
  340. .......
  341. }
  342. }
  343. }, 3000);
  344. }
  345. };
  346.  
  347.  
  348. @Override
  349. protected void onStart() {
  350. super.onStart();
  351. Wappier.getInstance().registerRedeemCallback(redeemListener);
  352. }
  353.  
  354. @Override
  355. protected void onStop() {
  356. super.onStop();
  357. Wappier.getInstance().unregisterRedeemCallBack();
  358. }
  359.  
  360. ```
  361.  
  362. When the transaction is completed and the user receives the reward you can call the following line to complete the redemption flow:
  363. ```
  364. // In case of success
  365. Wappier.getInstance().redemptionIsCompleted(true, redemptionId);
  366.  
  367. // In case of error
  368. Wappier.getInstance().redemptionIsCompleted(false, redemptionId);
  369. ```
  370.  
  371. ***Note: If we do not receive any of the above callbacks within 7 seconds, we’re going to treat this redemption as a failed one.***
  372.  
  373. You can refer to the following example, please don’t forget to call *redemptionIsCompleted* method as soon as possible:
  374. ```
  375. Wappier.registerRedeemCallback(new RedeemListener() {
  376. @Override
  377. public void redeemCallback(String sku, final String redemptionId, final int quantity) {
  378. // added delay to emulate a transaction
  379. final Handler handler = new Handler();
  380. handler.postDelayed(new Runnable() {
  381. @Override
  382. public void run() {
  383. if (sku.equals("test_sku_1") || sku.contains("test_sku_1")) {
  384. Wappier.getInstance().redemptionIsCompleted(true, redemptionId);
  385. }
  386. else {
  387. Wappier.getInstance().redemptionIsCompleted(false, redemptionId);
  388. }
  389. }
  390. }, 3000);
  391. }
  392. });
  393. ```
  394.  
  395. **Possible responses:**
  396. ```
  397. // Failed redemption due to a missing item ID
  398. Error buffer(com.android.okhttp.internal.http.Http1xStream$FixedLengthSource@8a15e97).inputStream() Message :{"error": "Reward is not found, is locked or claimed","code":916} Code :400
  399. ```
  400. ```
  401. // Failed redemption due to a game error
  402. Redeem sending demo.sku.com with Quantity : 5 to server
  403. Redeem Item found. 5000 will committed
  404. Calling mother app callback with SKU : demo.sku.com
  405. Redemption is Completed :false
  406. Redeem – Status: 1000
  407. Points restored
  408. ```
  409. ```
  410. // Successful redemption
  411. Redeem sending demo.sku.com with Quantity : 5 to server
  412. Redeem Item found. 5000 will committed
  413. Calling mother app callback with SKU : demo.sku.com
  414. Redemption is Completed :true
  415. Redeem – Status: 200
  416. Transaction Completed
  417. ```
  418.  
  419.  
  420.  
  421. ## **Regional Pricing using Control Group** (for Regional Pricing solution)<a name="regional-pricing-using-control-group"></a>
  422. You can enable dynamic pricing service via the wappier dashboard by assigning prices to your in app products. The new prices will be visible to a predefined percentage of the population while the rest of it will belong to a control group that will be used to compare performance.
  423. Users belonging in the control group will notice no differences in price points.
  424.  
  425. You normally send an SKU ID to Google's In App Billing API according to the guidelines described here. By using our pricing optimization service, the SKU is no longer a predefined constant but can rather change whenever the application launches.
  426.  
  427. For this reason, you have to fetch the assigned SKU based on the original SKU by using the below method (at the start of your activity and after the SDK has been initialized):
  428.  
  429. ```
  430. Wappier.getInstance().getSku(String originalSku);
  431. ```
  432.  
  433. For example, if you have an SKU named *'com.company.magic_sword'*, you should retrieve the name of the dynamically allocated equivalent of that SKU:
  434.  
  435. ```
  436. String regionalSku;
  437. public class MainActivity extends Activity {
  438. public void onCreate(Bundle savedInstanceState) {
  439. super.onCreate(savedInstanceState);
  440. regionalSku = Wappier.getInstance().getSku("com.company.magic_sword");
  441. //Now you can use the regionalSku in Google billing API related methods
  442. }
  443. }
  444. ```
  445.  
  446. In case of a failure (network issue or expired pricing test), methods returns the original SKU.
  447.  
  448. ## **PROPRIETARY NOTICE**
  449. This document and any files transmitted with it are confidential and intended solely for the use of the individual or entity to whom they are addressed. This message contains confidential information and is intended only for the individual or entity named. If you are not the named addressee you should not disseminate, distribute or copy this document.
  450.  
  451. If you are not the intended recipient you are notified that disclosing, copying, distributing or taking any action in reliance on the contents of this information is strictly prohibited.
  452.  
  453. The information contained in these documents is confidential, privileged and only for the information of the intended recipient and may not be used, published or redistributed without the prior written consent of wappier Ltd.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement