# iOS/Android clients integration guide

This document aims to provide guidelines for integrating Smartico services in mobile native applications (iOS/Android).

Depending on the integration scope, you may need to cover different areas described below

1. Points 1.1-1.6 should be supported in all integration scenarios
2. To support native push notifications - additionally points 1.8,1.9 and 4
3. To support Popups - point 1.10
4. To support the gamification widget & mini-games - point 1.11

Note: if your goal is to support only push notifications, you can implement only point 4.

## Communication layer

Smartico client integration supports secure WebSocket technology; integration with front-end protocols will allow you to implement some of the Smartico functionalities currently developed as stand-alone JS widgets and embedded on clients' websites.

* API URL has the address like wss\://api.smartico.ai/websocket/services?master\&domain={{your domain}}\&version={{your client code version}} (note that address could be different depending on your setup, please contact your account manager)
* Please consult your account manager for the API URL specific to your setup; the URL could differ from the one listed above.
* In the case of Native app integration, you can pass the application ID (e.g. myapp.company.com) instead of "your domain" and the version of the application (e.g. 1.2.29) instead of "your client code version" in the API URL
* All requests over web-socket should be in JSON format; examples are below.
* A clear sequence of commands should be followed to ensure the session is initiated correctly on the servers.
* Every request sent from client to server should contain two operations fields:
  * **ts** - is a Unix timestamp with milliseconds
  * **uuid** - random unique identifier of the request

## 1. Protocol Messages

### 1.1. INIT\_SESSION\_REQUEST

Use this API call to initialize websocket session

**Structure:**

| Field Name       | Data Type     | Description                                                                                                            |
| ---------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------- |
| cid              | Integer \*    | Class id, should be 3                                                                                                  |
| label\_key       | String \*     | A unique key represents the label on smartico side.                                                                    |
| brand\_key       | String \*     | A unique key represents the brand inside the smartico label (multi-brand solution) or null if the label is standalone. |
| device\_id       | String \*     | A unique key representing the current device used.                                                                     |
| page             | String \*     | For web integrations, the current URL in the user's browser                                                            |
| tracker\_version | String \*     | The version of the library that is sending requests. Format X.Y.Z                                                      |
| session\_id      | String \*     | Unique session ID generated on the client side                                                                         |
| ua               | Object (Json) | Additional data below                                                                                                  |

**Structure of the "ua" object**

| Field Name   | Data Type  | Description                                                                                                               |
| ------------ | ---------- | ------------------------------------------------------------------------------------------------------------------------- |
| fp           | Integer    | Fingerprint of device. Optional string that uniquely identified device                                                    |
| agent        | String     | Optional string that represent web browser user agent                                                                     |
| host         | String     | Optional, a domain that calls the API. Relevant for web-based integration                                                 |
| device\_type | String \*  | NATIVE\_PHONE or NATIVE\_TABLET                                                                                           |
| tzoffset     | Integer \* | <p>Very important to send player timezone offset in the same format web browser does it</p><p>Example: (GMT+3 = -180)</p> |
| os           | String \*  | 'iOS' or 'Android' for Native apps (or any other string for non-native)                                                   |

**Example:**

```json
{
  "cid": 3,
  "label_key": "6816ba80-2967-4efb-a60c-694c72b03197",
  "brand_key": null,
  "device_id": "2632f21a-cb84-4ce0-95ca-bf71debfc9c9",
  "ua": {
    "fp": 95408084,
    "agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",
    "host": "demo.smartico.ai",
    "device_type": "DESKTOP",
    "tzoffset": -180,
    "os": "Mac OS"
  },
  "page": "https://demo.smartico.ai/",
  "tracker_version": "1.1.277",
  "session_id": "a5719258-f6fc-4335-a4aa-a1e102e035ed",
  "ts": 1632832357494,
  "uuid": "c7067eb9-38e7-4b74-8d5e-e17d52c99465"
}
```

### 1.2 INIT\_SESSION\_RESPONSE

The message will come to the client as a response to INIT\_SESSION\_REQUEST and will bring essential information for client's booting logic.

**Structure:**

| Field Name | Data Type  | Description                                                                                                                                                                                                     |
| ---------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| cid        | Integer \* | Class id, should be 4                                                                                                                                                                                           |
| errCode    | Integer \* | <p>0 > all good</p><p>1 > Same error happened</p>                                                                                                                                                               |
| errMsg     | String     | <p><br></p>                                                                                                                                                                                                     |
| ts         | Long       | Server time                                                                                                                                                                                                     |
| uuid       | String     | Unique message Id                                                                                                                                                                                               |
| products   | Int \[]    | <p>An array of products enabled for this label. The only important product for now is</p><p>GAMIFICATION = 100.</p><p>Availability of gamification product means that end-user can open gamification widget</p> |
| payload    | Object     | Technical information about user session.                                                                                                                                                                       |
| settings   | Object     | Key<>Value pairs of settings are described below.                                                                                                                                                               |

**Structure of the PAYLOAD object**

| Field Name | Data Type | Description                        |
| ---------- | --------- | ---------------------------------- |
| country    | String    | Country the way server thinks it’s |
| city       | String    | City the way server thinks it’s    |
| ip         | String    | IP address server sees             |
| s          | String    | ignore                             |

**Structure of the SETTINGS object**

| Field Name             | Data Type | Description                                                                                                     |
| ---------------------- | --------- | --------------------------------------------------------------------------------------------------------------- |
| FCM\_SENDER\_ID        | String    | Firebase sender ID that should be used to get push notifications token                                          |
| DYNAMIC\_IMAGE\_DOMAIN | String    | URL to images server.Used to load the avatar of the user. (see explanation in IDENTIFY\_RESPONSE message below) |

**Example:**

```json
{
  "cid": 4,
  "errCode": 0,
  "errMsg": null,
  "ts": 1632835680057,
  "uuid": "8a9c31be-455d-4ff7-ad96-5f8b84ba11f4",
  "products": [
    100,
    0,
    5
  ],
  "payload": {
    "country": "BG",
    "s": "main03",
    "city": "Sofia",
    "ip": "84.252.11.15",
    "sessionId": "172f"
  },
  "settings": {
    "FCM_SENDER_ID": "123",
    "DYNAMIC_IMAGE_DOMAIN": "https://img.smr.vc/"
  }
}
```

### 1.3. PING

The server will periodically ping the client to ensure the connection remains open, and the client should respond with a PONG message promptly.

**Structure:**

| Field Name | Data Type  | Description           |
| ---------- | ---------- | --------------------- |
| cid        | Integer \* | Class id, should be 1 |

```json
{
  "cid": 1,
  "ts": 1632897982843,
  "uuid": "dcc747c1-4a3b-4cb1-a62d-7095f01c16a7"
}
```

### 1.4. PONG

The client should send this message when the server sends a PING.

**Structure:**

| Field Name | Data Type  | Description           |
| ---------- | ---------- | --------------------- |
| cid        | Integer \* | Class id, should be 2 |

```json
{
  "cid": 2,
  "ts": 1632897982843,
  "uuid": "dcc747c1-4a3b-4cb1-a62d-7095f01c16a7"
}
```

### 1.5 IDENTIFY\_USER\_REQUEST

Should be sent as soon as the user is logged in.

Note: When the user logs out, you will need to close the WebSocket and reopen it. In other words, user identification should be performed only once per WebSocket session.

**Structure:**

| cid                        | Integer \*    | Class id, should be 5                                                                                                                                                                                                                                                                                                                                                |
| -------------------------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ext\_user\_id              | String \*     | Id of the user                                                                                                                                                                                                                                                                                                                                                       |
| token                      | String        | Push notification token                                                                                                                                                                                                                                                                                                                                              |
| platform                   | Integer       | <p>enum PushClientPlatform {</p><p>CHROME\_DESKTOP = 0,</p><p>FIREFOX\_DESKTOP = 1,</p><p>EDGE\_DESKTOP = 2,</p><p>OPERA\_DESKTOP = 3,</p><p>SAFARI\_DESKTOP = 4,</p><p>OTHER = 5,</p><p>NATIVE\_IOS = 6,</p><p>NATIVE\_ANDROID = 7,</p><p>CHROME\_MOBILE = 8,</p><p>FIREFOX\_MOBILE = 9,</p><p>SAFARI\_MOBILE = 10,</p><p>OPERA\_MOBILE = 11</p><p>}</p><p><br></p> |
| pushNotificationUserStatus | Integer       | <p>Status of push notifications on the end-user device/browser</p><p>enum PushNotificationUserStatus {</p><p>ALLOWED = 0,</p><p>ASK = 1,</p><p>BLOCKED = 2,</p><p>SUSPENDED = 3,</p><p>NOT\_SUPPORTED = 4</p><p>}</p><p><br></p>                                                                                                                                     |
| page                       | String        | In case of web integration, current URL in the browser                                                                                                                                                                                                                                                                                                               |
| ua                         | Object (Json) | Same as UA object explained above                                                                                                                                                                                                                                                                                                                                    |
| tracker\_version           | string        | The version of the native app will be available for segmenting users in Smartico backoffice by the last reported version using the property core\_tracker\_version                                                                                                                                                                                                   |

**Example:**

```json
{
	"cid": 5,
	"ext_user_id": "test6209240",
	"hash": null,
	"ua": {
		"fp": -1461686277,
		"agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1",
		"host": "mysite.com",
		"device_type": "MOBILE",
		"tzoffset": -180,
		"browser": "Safari",
		"os": "Mac OS"
	},
	"page": "https://mysite.com",
	"pushNotificationUserStatus": 0,
	"token": "fwU4rhKj3Ww:AP...iQ",
	"tracker_version": "1.23.546",
	"platform": 10,
	"payload": {},
	"ts": 1632911887307,
	"uuid": "e172c925-272a-4004-81fe-b8177a240af5"
}
```

### 1.6 IDENTIFY\_USER\_RESPONSE

Will be sent from server to client as a response to INDENTIFY\_USER\_REQUEST

**Structure:**

| cid                     | Integer \* | Class id, should be 6                                                                                                                                                                                                                                                                                              |
| ----------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| public\_username        | String \*  | Username                                                                                                                                                                                                                                                                                                           |
| avatar\_id              | String \*  | <p>ID of avatar that can be used with DYNAMIC\_IMAGE\_DOMAIN to build URL to avatar, e.g.</p><p><a href="https://img.smr.vc/avatar/17404556"><https://img.smr.vc/avatar/17404556></a></p>                                                                                                                          |
| native\_app\_gf\_url    | String     | Gamification wrapper url including the label\_key (including the env id), brand key, user’s external id and 24 hour validity hash (only for labels support user hash validation)                                                                                                                                   |
| native\_app\_popup\_url | String     | Engagement wrapper url including the label\_key (including the env id), brand key, user’s external id and 24 hour validity hash (only for labels support user hash validation)                                                                                                                                     |
| props                   | Key<>Value | <p>Set of user information that can be useful to build additional info in the UI.</p><p>Important properties:</p><p>core\_is\_test\_account, that is indicated that logged in user is test user.</p><p>It can be used for the development purpose to unveil not released functionality for the test users only</p> |

**Example:**

```json
{
	"props": {
		"ach_points_ever": 3605,
		"ach_points_balance": 3570,
		"ach_level_current": "Level E",
		"core_is_test_account": false
	},
	"public_username": "test6209240",
	"avatar_id": "3902924573654987",
  "native_app_gf_url": "https://libs.smartico.ai/wrapper-gf.html?label_key=d78934f3-1d8b-461b-9e8f-287aae43c860-2&brand_key=c24a284e&user_ext_id=test6209240",
	"native_app_popup_url": "https://libs.smartico.ai/wrapper-popup.html?label_key=d78934f3-1d8b-461b-9e8f-287aae43c860-2&brand_key=c24a284e&user_ext_id=test6209240",
	"errCode": 0,
	"errMsg": null,
	"cid": 6,
	"ts": 1632911887478,
	"uuid": "2d1eff13-a3d3-49ba-b1a0-50e1a51f1574"
}

```

### 1.7 LOGIN

Optionally, it can be sent when a new user session is created.

**Reasoning for sending "Login" event.**

Smartico server has a special event called "Core: user went online" that can be used to start campaigns, automation rules, complete missions, etc. The limitation of this event is that it's triggered every time "IDENTIFY\_USER\_REQUEST" is sent from the native application or web.

This limits businesses from using this event for operational purposes, as it will also be triggered on any reconnection or re-establishment of the socket (e.g., the application went into the background for a while and then returned to the active state).

To mitigate this issue, Smartico supports a "Login" event logic that can be sent by the web or native application when a logical session starts.

The native app should define the definition of the new logical session

In the web context, Smartico sends a "Login" event automatically when the user comes online after a minimum of 30 minutes of inactivity.

**Structure:**

| Field Name  | Data Type     | Description                       |
| ----------- | ------------- | --------------------------------- |
| cid         | Integer \*    | Class id, should be 7             |
| payload->ua | Object (Json) | Same as UA object explained above |

**Example:**

```json
{
	"cid": 7,
	"payload": {
		"ua_fp": -287665022,
		"ua_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36",
		"ua_host": "demo.smartico.ai",
		"ua_device_type": "DESKTOP",
		"ua_tzoffset": -120,
		"ua_browser": "Chrome",
		"ua_os": "Mac OS"
	},
	"ts": 1667224781660,
	"uuid": "00059fd6-fee0-45f0-a319-c8b12e1f226b"
}
```

### 1.8 REGISTER\_PUSH\_NOTIFICATIONS\_TOKEN\_REQUEST

Should be sent by Client to Server in case push token for notifications is obtained, changed, or no longer valid.

**Structure:**

| Field Name                 | Data Type  | Description                                                                                                                                                                                                                                                                                                                                                          |
| -------------------------- | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| cid                        | Integer \* | Class id, should be 1003                                                                                                                                                                                                                                                                                                                                             |
| token                      | String \*  | Push notification token                                                                                                                                                                                                                                                                                                                                              |
| platform                   | Integer    | <p>enum PushClientPlatform {</p><p>CHROME\_DESKTOP = 0,</p><p>FIREFOX\_DESKTOP = 1,</p><p>EDGE\_DESKTOP = 2,</p><p>OPERA\_DESKTOP = 3,</p><p>SAFARI\_DESKTOP = 4,</p><p>OTHER = 5,</p><p>NATIVE\_IOS = 6,</p><p>NATIVE\_ANDROID = 7,</p><p>CHROME\_MOBILE = 8,</p><p>FIREFOX\_MOBILE = 9,</p><p>SAFARI\_MOBILE = 10,</p><p>OPERA\_MOBILE = 11</p><p>}</p><p><br></p> |
| pushNotificationUserStatus | Integer \* | <p>Status of push notifications on the end-user device/browser</p><p>enum PushNotificationUserStatus {</p><p>ALLOWED = 0,</p><p>ASK = 1,</p><p>BLOCKED = 2,</p><p>SUSPENDED = 3,</p><p>NOT\_SUPPORTED = 4</p><p>}</p><p><br></p>                                                                                                                                     |

**Example:**

```json
{
	"cid": 1003,
	"pushNotificationUserStatus": 0,
	"token": "fwU4rhKj3Ww:AP...iQ",
	"platform": 10,
	"ts": 1632911887307,
	"uuid": "e172c925-272a-4004-81fe-b8177a240af5"
}
```

1.9 REGISTER\_PUSH\_NOTIFICATIONS\_TOKEN\_RESPONSE

Will be sent from Server to Client as a response to INDENTIFY\_USER\_REQUEST

**Structure:**

| Field Name | Data Type  | Description              |
| ---------- | ---------- | ------------------------ |
| cid        | Integer \* | Class id, should be 2003 |

Example:

```json
{
    "errCode": 0,
    "errMsg": null,
    "cid": 2003,
    "ts": 1632913275700,
    "uuid": "fd6ea980-d379-41f0-aec8-384dfc60885a"
}
```

### 1.10 CLIENT\_ENGAGEMENT\_EVENT

Sent by the server at the time when a Pop-up message should be shown to the end user.

In the case of Native app implementation, the front-end library should:

1. Create a hidden web-view using the URL from the settings native\_app\_popup\_url
2. Inject the full payload of the event to the WRAPPER page using the “smarticoBridge” interface (explained below)
3. Display a web-view
4. Listen for the “close” event from the webview to remove it from the native UI

**Structure:**

The client should look only for the "cid" with value 110 and be transparent for any other fields in the event.

**Example**

```json
{
	"engagement_uid": "06f0cd67-ec24-4eeb-bbe9-c3529e8743fa",
	"activityType": 30,
	"engagement_id": 236356783,
	"root_audience_id": 31068,
	"audience_id": 31068,
	"resource_id": 5843,
	"resource_variation_id": 5843,
	"template_html": "...",
	"template_engine": 1,
	"params": {
       ...
	},
	"source_product_id": 0,
	"cid": 110,
	"ts": 1632913275835,
	"uuid": "df4a39fb-0536-4c68-9c32-0c1db7e75588",
}

```

### 1.11 CORE\_LANGUAGE\_CHANGE

In case the user changes the language in the native application (not wrapper) Client should send to Server the core\_language\_change event.

**Structure:**

| Field Name          | Data Type     | Description                                                                                                                                                                                                              |
| ------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| cid                 | Integer \*    | Class id, should be 9                                                                                                                                                                                                    |
| eventType           | String \*     | Should be core\_language\_changed                                                                                                                                                                                        |
| payload             | Object (Json) | <p><br></p>                                                                                                                                                                                                              |
| payload -> language | String \*     | <p>ISO 639-1 code of user language (2 symbols code).</p><p><br>If you need to support languages with regional codes like "pt-br", please check for the <a href="..#custom-language-codes">custom language codes</a>.</p> |
| ts                  | Integer \*    | Timestamp in ms                                                                                                                                                                                                          |
| uuid                | String \*     | Unique id of the request (format should be uuid)                                                                                                                                                                         |

**Example:**

```json
{
  "eventType": "core_language_changed",
  "payload": {
    "language": "EN"
  },
  "ts": 1761648788170,
  "uuid": "8ca5ac3a-9211-452f-9da9-0fef1a2ef477"
}

```

### 1.12 SAW\_SHOW\_SPIN\_PUSH

Sent by the Server to the Client at the time when a Mini-game needs to be shown to the end user.

In the case of Native app implementation, the front-end library should:

1. Create a hidden web-view using URL from the identify user response (native\_app\_gf\_url property)
   1. Example of URL: <https://libs.smartico.ai/wrapper-gf.html?label_key=d78934f3-1d8b-461b-9e8f-287aae43c860-2&brand_key=c24a284e&user_ext_id=test6209240>
   2. Additionally, append to the url deep-link to open the Mini-game with the specified saw\_template\_id - "dp:gf\_saw\&id=5\&standalone=true". Note that this deep link should be URL encoded.
   3. The final URL should look like: <https://libs.smartico.ai/wrapper-gf.html?label_key=d78934f3-1d8b-461b-9e8f-287aae43c860-2&brand_key=c24a284e&user_ext_id=test6209240&dp=dp%26gf_saw%26id%3D5%26standalone%3Dtrue>
2. Display a web-view
3. Listen for the “close” event from the webview to remove it from the native UI.

**Structure:**

| Field Name | Data Type  | Description             |
| ---------- | ---------- | ----------------------- |
| cid        | Integer \* | Class id, should be 707 |

**Example:**

```json
{
	"saw_template_id": 5,
	"cid": 707,
	"ts": 1652873739950,
	"uuid": "4d9263b6-9f2e-4951-a819-64879568baec",
}

```

<br>

## 2. Main flow

1. The user is opening the Native app and logging in
2. The native app is establishing WebSocket connection using API URL explained above
3. The native app is sending **INIT\_SESSION\_REQUEST** and waiting for the response
4. The native app is sending **IDENTIFY\_USER\_REQUEST** and waiting for the response
5. The native app keeps WebSocket connection open and listening for **CLIENT\_ENGAGEMENT\_EVENT**. Whenever it's sent, the Native app should display engagement (also called popup) using WebView/Native Bridge implementation
6. If there is a change in Push notification statutes, the Native app should inform it either on the next **IDENTIFY\_USER\_REQUEST** if the session is not active right now or using **REGISTER\_PUSH\_NOTIFICATIONS\_TOKEN\_REQUEST**
7. The native app should listen for **EXECUTE\_DEEP\_LINK** event from Native Bridge and execute the needed action

The native app should provide a button in the native interface to open a Gamification widget. The process of opening the Gamification widget is explained in the protocol above, and using **native\_app\_gf\_url**

**Note:** WebViews that will be used to show gamification widgets and to show a pop-up (as a reaction to CLIENT\_ENGAGEMENT\_EVENT) should be 2 independent instances. The reason for this is that it's possible to have a Gamification Widget opened and visible to the end user, while the Smartico server simultaneously sends a CLIENT\_ENGAGEMENT\_EVENT that displays the pop-up. An opposite flow is also possible; the pop-up triggered by CLIENT\_ENGAGEMENT\_EVENT can have a deep link that should open the Gamification widget.

## 3. Native Bridge

The native client uses WebView to load the Gamification widget and Engagement page (Including Pop-Ups).

In this process, the Native client and loaded Web page should be able to communicate using JSON messages through the "Native Bridge" interface.

The webview should have its user agent set to “SMTO-WRAPPER” before being loaded.

The code below shows an example of bridge implementation for the Android platform. A similar implementation should be done for the iOS Platform.

```java

private void launchWebView(String siteUrl) {
   WebView webView = (WebView) findViewById(R.id.boWebView);
   PostMessage x = new PostMessage(webView, this);
   WebSettings webSettings = webView.getSettings();
   webSettings.setUserAgentString(“SMTO-WRAPPER”);
   webSettings.setJavaScriptEnabled(true);
   webSettings.setDomStorageEnabled(true);
   webView.addJavascriptInterface(x, "SmarticoBridge");
   webView.loadUrl(siteUrl);
}

public class PostMessage {
   private final WebView webView;
   private final Context ctx;

   public PostMessage(WebView webView, Context ctx) {
       this.webView = webView;
       this.ctx = ctx;
   }

   @JavascriptInterface
   public boolean postMessage(String data) throws JSONException {
       JSONObject msg = new JSONObject(data);
       int classId = msg.getInt("bcid");
       if (classId == 1) {
           JSONObject message = new JSONObject();
           message.put("bcid", 3);
     	     // here to be a code populating Engagement event into the bridge message
           this.sent(message);
       }
       return true;
   }


   public void sent(final JSONObject message) throws JSONException {
       webView.post(new Runnable() {
           @Override
           public void run() {
               String sMessage = message.toString();
               webView.loadUrl("javascript:window.postMessage('" + sMessage + "', '*');");
           }
       });
   }
}

```

Note: if you are using the react-native-webview package, the bridge will be named ReactNativeWebView and will be supported as well. You can also send messages from Native to WebView using injectJavaScript method.

Please refer to the official documentation for more details - <https://github.com/react-native-webview/react-native-webview/blob/master/docs/Guide.md#communicating-between-js-and-native>

There are following messages could be sent betweenthe Native client and the loaded page:

### 3.1 PAGE\_READY (Web to Native). BCID = 1

Message sent by web page to the native client notifying that page is loaded and ready to accept new messages.

Note: Native client should send any messages addressed to the Wrapped page only after getting PAGE\_READY

```json
{
	"bcid": 1
}
```

### 3.2 CLOSE\_ME (Web to Native), BCID = 2

Message sent by the web page to the native client notifying that the native client should close the webview.

Example of message:

```json
{
	"bcid": 2
}
```

### 3.3 SHOW\_ENGAGEMENT (Native to Web), BCID = 3

Message sent by Native client to web page with the full payload of CLIENT\_ENGAGEMENT\_EVENT. The web page will display the Popup UI

```json
{
	"bcid": 3,
  "engagement_uid": "06f0cd67-ec24-4eeb-bbe9-c3529e8743fa",
	"activityType": 30,
	"engagement_id": 236356783,
	"root_audience_id": 31068,
	"audience_id": 31068,
	"resource_id": 5843,
	"resource_variation_id": 5843,
	"template_html": "...",
	"template_engine": 1,
	"params": {
       ...
	},
	"source_product_id": 0,
	"cid": 110,
	"ts": 1632913275835,
	"uuid": "df4a39fb-0536-4c68-9c32-0c1db7e75588"
}
```

### 3.4. EXECUTE\_DEEP\_LINK (Web to Native), BCID = 4

Message sent by the web page to the Native client to execute a specific action in the native interface. The exact list of actions depends on the integrated platform; the most common message is “dp:cashier” that is opening the Cashier page in the native interface.

```json
{
	"bcid": 4,
	"dp": "dp:gf_levels"
}
```

You can consider 3 types of deep-links

**"Dummy" deep-links**

Such links are used in the Popups (engagements), they are - "dp:ok", "dp:cancel" and "dp:close" and "dp:action".

The Native application should ignore such deep links as they don't have functionality and are used only to progress flows in the marketing campaigns.

**Gamification related deep-links**

These deep links navigate to specific sections of the gamification widget.

These are all deep links listed here - <https://help.smartico.ai/welcome/products/general-concepts/deep-links>

Except "dp:action" and "dp:inbox"

The Native app should use the URL to the gamification wrapper page (native\_app\_gf\_url) to start a gamification widget and pass a deep link to the URL in the encoded way.

Example of URL:

<https://libs.smartico.ai/wrapper-gf.html?label_key=d78934f3-1d8b-461b-9e8f-287aae43c860-2&brand_key=c24a284e&user_ext_id=test6209240&dp=dp:gf_store>

**Custom deep links (product specific deep-links)**

Links that are specific to the integrated platform/app and need to be handled fully by the native application, e.g. "dp:cashier"

### 3.5. READY\_TO\_BE\_SHOWN (Web to Native), BCID = 5

Message sent by web page to Native client to inform native client that the content of the webview is rendered and can now be shown.

```json
{
	"bcid": 5,
}
```

### 3.6. SEND\_TO\_SOCKET (Web to Native), BCID = 6

Message sent by web page to Native client and should be forwarded to the Smartico server through the websocket protocol.

```json
{
	"bcid": 6,
	"cid": 123,
	...more properties could be here...
}
```

### 3.7. SEND\_PUBLIC\_PROPS (Web to Native), BCID = 7

Message sent by the web page to the Native client whenever some public properties of the user are updated. This is a full alternative to the web implementation explained here - <https://help.smartico.ai/welcome/technical-guides/front-end-integration/extended-integration#user-profile-details>

It can be used to display user's current gamification points balance, avatar, etc.

```json
{
	"bcid": 7,
	"ach_points_balance": 55
}
```

### 3.8. SEND\_GAME\_OPENING (Web to Native), BCID = 8

A message is sent by the web page to the Native client whenever the user wants to start a casino game related to a mission or tournament.

More details can be found in the game catalog section here - <https://help.smartico.ai/welcome/technical-guides/games-catalog-api>

```json
{
	 "bcid": 8,
    "ach_game_id": 32, // ID of the game on smartico side
    "game_public_meta": { 
        "image": "https://mysite.com/images/card_2x/1x2gaming-InstantFootball-1674738298.jpg",
        "name": "Instant Football",
        "enabled": true
    },
    "ext_game_id": "56", // the ID of the game on the provider side
    "context": "mission" // context of the callback - mission or tournament
}
```

## 4. Registering tokens for push notifications over API

If you are already covering the general integration protocol described above and reporting push tokens over the WebSocket connection, you can skip this section.

Alternatively, you can report push tokens in one of the following 3 ways:

* Via POST Request
* Via GET Request
* Via JavaScript function call

Note: If you have different Firebase projects for Desktop, Android, and iOS, then you should send us the package\_id and also report it with the registration method (if you use the same project, then this is not needed).

If you choose to use HTTP-POST or HTTP-GET request, it should be to one of the following endpoints (depending on which **environment** your label is set):

* <https://papi2.smartico.ai/services/public>
* <https://papi3.smartico.ai/services/public>
* <https://papi4.smartico.ai/services/public>
* etc.

**Registering push token via POST Request**

You can report a push token using a simple POST request that has the following structure:

```json
{
    "app_package_id": "xxx.yyy.zzz", // bundle id for ios, app_package_name for android
    "brand_key": "xxxxx", // brand_key
    "api_key": "xxxxx", // label_key
    "ext_user_id": "xxxxx", //user id in the platform
    "pushNotificationUserStatus": 0, // this is always 0
    "platform": 7, // 6 iOS, 7 Android
    "cid": 1003, // always 1003
    "token": "cDWUiFOgR6ygfj6qUExJXv:APA91bGYKl93Qa6bfn_hNNUKnjc0QXhDJV8ESxMD66RMpw_5Phbc0An0JfbH3SJnl-zQIzU90motnpbwV9fYgF02hqEaM80Y5rT30gPR3c4wew3Ex8TPI9A"
}
```

**Registering push token via GET Request (not recommended)**

You can report a push token using a simple HTTP GET request to the URL described above.

The format of the request should be as below (replace X with ID of your environment):

<https://papiX.smartico.ai/services/public?api\\_key={your\\_api\\_key}\\&brand\\_key={your\\_brand\\_key}\\&version=1.2.25\\&event={event\\_body}>

Event Body structure, format it as string and do URL Encode:

```json
{
    // unique uuid for the request event
    "uuid": "acb841b7-d6d0-44c9-8a40-682219eaebf6",
    // timestamp of the request in epoch with milliseconds
    "ts": 1711695978141,
    // or whatever name you give, but in fact it's not event
    "event_type": 'register_push_token',
    // user id in your platform, can be integer or string.
    "user_ext_id": 12345,
    "payload": {
        "app_package_id": "xxx.yyy.zzz", // bundle id for ios, app_package_name for android
        "token": "push token should be here"
        // 6 for iOS and 7 for Android
        "platform": 6,
        // keep it always 0 as indicator that user gave permission
        "pushNotificationUserStatus": 0,
    }
}
```

**Registering push token via JavaScript**\
If your application is a native "wrapper" that uses a WebView to load your mobile web interface, it might be easier for you to report the token via a simple JavaScript function call. Here is how to do that:

1. Check request permissions and generate a push token
2. Pass the token to smartico by calling JavaSript:

```javascript
_smartico.registerNativePushToken(
    "your_token_here",
    platformId, // 6 for iOS and 7 for Android
    app_package_id // bundle id for ios, app_package_name for android
)
```

## 5. Reporting impressions, and "clicks" for push notifications over API

A native app can report the impression (when the push was displayed to the end-user) and click to Smartico.

This should be done with a simple HTTP-GET request to one of the following endpoints (depending on which **environment** your label is set):

* <https://papi2.smartico.ai/services/public>
* <https://papi3.smartico.ai/services/public>
* <https://papi4.smartico.ai/services/public>
* etc.

The format of the request should be as below (replace X with ID of your environment):

<https://papiX.smartico.ai/services/public?api\\_key={your\\_api\\_key}\\&brand\\_key={your\\_brand\\_key}\\&version=1.2.25\\&event={event\\_body}>

The label and brand keys here are the same as are used on the user identification.

The version may represent the version of the application and is intended for use only during debugging purposes.

**Reporting Fail**

The event\_body for failure should be built in the following way (example of code for React Native, similar can be done on other platforms):

```javascript
{
	uuid: generateGUID(), // unique uuid for each event
	ts: (new Date()).getTime(), // timestamp of the event
	event_type: 'engagement_failed',
	user_ext_id: message.data.user_ext_id, // user id, taken from the message
	payload: {
  	// more details that should be taken from the push message payload
		engagement_uid: message.data.engagement_uid,
		message_id: parseInt(message.data.message_id),
		activity_type: 40, // it should be always 40 for push notifications
	}
}
```

**Reporting Delivery**

The event\_body for delivery should be built in the following way (example of code for React Native, similar can be done on other platforms):

```javascript
{
	uuid: generateGUID(), // unique uuid for each event
	ts: (new Date()).getTime(), // timestamp of the event
	event_type: 'engagement_delivered',
	user_ext_id: message.data.user_ext_id, // user id, taken from the message
	payload: {
	  // more details that should be taken from the push message payload
		engagement_uid: message.data.engagement_uid,
		message_id: parseInt(message.data.message_id),
		activity_type: 40, // it should be always 40 for push notifications
	}
}

```

**Reporting Impression**

The event\_body for impression should be built in the following way (example of code for React Native, similar can be done on other platforms)

```javascript
{
	uuid: generateGUID(), // unique uuid for each event
	ts: (new Date()).getTime(), // timestamp of the event
	event_type: 'engagement_impression',
	user_ext_id: message.data.user_ext_id, // user id, taken from the message
	payload: {
  	// more details that should be taken from the push message payload
		engagement_uid: message.data.engagement_uid,
		message_id: parseInt(message.data.message_id),
		activity_type: 40, // it should be always 40 for push notifications
	}
}

```

**Reporting action (click)**

The event body for the click action:

```javascript
{
	uuid: generateGUID(), // unique uuid for each event
	ts: (new Date()).getTime(), // timestamp of the event
	event_type: 'engagement_action',
	user_ext_id: message.data.user_ext_id, // user id, taken from the message
	payload: {
	// more details that should be taken from the push message payload
		engagement_uid: message.data.engagement_uid,
		message_id: parseInt(message.data.message_id),
		activity_type: 40, // it should be always 40 for push notifications
		action: message.data.action
	}
}
```

```json
{
    "errCode": 0,
    "detailMessage": "",
    "stackTrace": [],
    "suppressedExceptions": []
}
```
