Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 109 additions & 0 deletions BridgeAPI.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ native modules for both platforms: Android and iOS.
- getLookupData
- getExperiences
- experienceShown
- getPlacement
- placementImpression
- placementClickthrough

-------------------------------------------------------
## **init(trackingId, logLevel)**
Expand Down Expand Up @@ -293,3 +296,109 @@ None

### Example
QubitSDK.experienceShown("https://sse.qubit.com/v1/callback?data=igK....n0=");

-------------------------------------------------------

## **getPlacement**(placementId, mode, attributes, campaignId, experienceId, placementPromise)

### Description
Returns Placement for given parameters.

### Parameters
- placementId
- Type: String
- Constraints: Not null
- Description: Unique ID of the placement.
- mode
- Type: String
- Constraints: Can be one of LIVE/SAMPLE/PREVIEW.
- Description: The mode to fetch placements content with. Defaults to LIVE.
- attributes
- Type: String
- Constraints: Should be string description of JSON or null
- Description: JSON string containing custom attributes to be used to query for the placement. "visitor" attribute will be ignored as it is set by SDK.
- campaignId
- Type: String
- Constraints: Nullable
- Description: Campaign identifier
- experienceId
- Type: String
- Constraints: Nullable
- Description: Experience identifier

### Result
Promise with a map describing Placement object:

{
"content": { ... }
"impressionUrl": "https://api.qubit.com/placements/callback?data=ggW4eyJtZXRhIjp7ImlkIjo",
"clickthroughUrl": "https://api.qubit.com/placements/callback?data=mQW4eyJtZXRhIjp7Imlkx"
}
The structure of response content depends on the type of placement that is being called.

### Exceptions
- Exception is thrown, when SDK is not initialized.

### Example
async () => {
const placement = await QubitSDK.getPlacement(
"placement_id",
"LIVE",
"{ \"color\": \"blue\"}",
"campaign_id",
"experience_id"
);
...
}

-------------------------------------------------------

## placementImpression(callbackUrl)

### Description
Sends request to URL described by placement impression callback.

### Parameters
- callbackUrl
- Type: String
- Constraints: Not null
- Description: Impression callback URL.


### Result
None

### Example
async () => {
const placement = await QubitSDK.placementImpression(
"https://some.url.com"
);
...
}

-------------------------------------------------------

## placementClickthrough(callbackUrl)

### Description
Sends request to URL described by placement clickthrough callback.

### Parameters
- callbackUrl
- Type: String
- Constraints: Not null
- Description: Clickthrough callback URL.


### Result
None

### Example
async () => {
const placement = await QubitSDK.placementClickthrough(
"https://some.url.com"
);
...
}


47 changes: 43 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ Installation of the QubitSDK, to provide event tracking and lookup. To make use

### Installation

1. `$ npm install qubit-sdk-react-native --save`
or
`$ yarn add qubit-sdk-react-native`
1. `$ npm install qubit-sdk-react-native --save`
or
`$ yarn add qubit-sdk-react-native`

2. Navigate to your `/ios` directory and run `pod install` to ensure the `QubitSDK` CocoaPod is installed. Android should require no further installation.
2. Navigate to your `/ios` directory and run `pod install` to ensure the `QubitSDK` CocoaPod is installed. Android should require no further installation.

Optional - if you are using React Native < 0.60, you must `link` the library.

Expand Down Expand Up @@ -54,6 +54,9 @@ and send first event
- [getExperiences](#getexperiences)
- [Parameters](#parameters-3)
- [Examples](#examples-6)
- [getPlacement](#getplacement)
- [Parameters](#parameters-4)
- [Examples](#examples-7)

#### start

Expand Down Expand Up @@ -214,6 +217,42 @@ async () => {

Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<Experience>>** Promise with an array of Experience objects.

#### getPlacement

Returns Placement for given parameters.

##### Parameters

- `placementId` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Unique ID of the placement.
- `mode` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** The mode to fetch placements content with, can be one of LIVE/SAMPLE/PREVIEW. Defaults to LIVE.
- `attributes` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** JSON string containing custom attributes to be used to query for the placement. "visitor" attribute will be ignored as it is set by SDK.
- `campaignId` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** Optional.
- `experienceId` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** Optional.

##### Examples

```javascript
async () => {
const placement = await getPlacement(
"placement_id",
"LIVE",
"{ \"color\": \"blue\"}",
"campaign_id",
"experience_id"
);
...
placement.impression();
...
placement.clickthrough();
}

{
"content": { ... }
}
```

Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<Placement>** Promise with an object describing Placement object.

### Compatibility

Qubit SDK React Native is compatible with React Native 0.58 and higher
Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,6 @@ dependencies {

implementation "androidx.annotation:annotation:1.0.0"
implementation "com.google.code.gson:gson:2.8.2"
implementation 'com.qubit:qubit-sdk-android:1.4.1'
implementation 'com.qubit:qubit-sdk-android:2.0.1'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.0"
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.qubit.reactnative.sdk;

import android.util.Log;
import androidx.annotation.NonNull;

import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
Expand All @@ -12,18 +12,24 @@
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.qubit.android.sdk.api.QubitSDK;
import com.qubit.android.sdk.api.logging.QBLogLevel;
import com.qubit.android.sdk.api.placement.PlacementMode;
import com.qubit.android.sdk.api.placement.PlacementPreviewOptions;
import com.qubit.android.sdk.api.tracker.event.QBEvent;
import com.qubit.android.sdk.api.tracker.event.QBEvents;
import com.qubit.android.sdk.internal.experience.Experience;
import com.qubit.android.sdk.internal.experience.callback.CallbackConnector;
import com.qubit.android.sdk.internal.experience.callback.CallbackConnectorImpl;
import com.qubit.android.sdk.internal.experience.callback.ExperienceCallbackConnector;
import com.qubit.android.sdk.internal.experience.callback.ExperienceCallbackConnectorImpl;
import com.qubit.android.sdk.internal.experience.model.ExperiencePayload;
import com.qubit.android.sdk.internal.lookup.LookupData;

import java.util.ArrayList;
import java.util.List;

import androidx.annotation.NonNull;


public class QubitSDKModule extends ReactContextBaseJavaModule {
private static ReactApplicationContext reactContext;
Expand Down Expand Up @@ -139,18 +145,76 @@ public void getExperiences(ReadableArray experienceIds,

@ReactMethod
public void experienceShown(String callback) {
CallbackConnector callbackConnector = new CallbackConnectorImpl(callback, QubitSDK.getDeviceId());
ExperienceCallbackConnector callbackConnector = new ExperienceCallbackConnectorImpl(callback, QubitSDK.getDeviceId());
callbackConnector.shown();
}

@ReactMethod
public void getPlacement(
String placementId,
String mode,
String attributes,
String campaignId,
String experienceId,
Promise placementPromise
) {
QubitSDK.getPlacement(
placementId,
matchMode(mode),
getAttributesJson(attributes),
new PlacementPreviewOptions(campaignId, experienceId),
placement -> {
JsonObject placementJson = new JsonObject();
placementJson.add("content", placement.getContent());
placementJson.addProperty("impressionUrl", placement.getImpressionUrl());
placementJson.addProperty("clickthroughUrl", placement.getClickthroughUrl());
placementPromise.resolve(WritableMapConverter.convertJsonToMap(placementJson));
return null;
},
throwable -> {
placementPromise.reject(throwable);
return null;
}
);
}

@ReactMethod
public void placementImpression(String callbackUrl) {
QubitSDK.sendCallbackRequest(callbackUrl);
}

@ReactMethod
public void placementClickthrough(String callbackUrl) {
QubitSDK.sendCallbackRequest(callbackUrl);
}

private PlacementMode matchMode(String value) {
switch (value) {
case "SAMPLE":
return PlacementMode.SAMPLE;
case "PREVIEW":
return PlacementMode.PREVIEW;
case "LIVE":
default:
return PlacementMode.LIVE;
}
}

private JsonObject getAttributesJson(String attributes) {
try {
return new JsonParser().parse(attributes).getAsJsonObject();
} catch (Exception e) {
return null;
}
}

private static QBLogLevel defaultLogLevel = QBLogLevel.WARN;

private QBLogLevel parseLogLevel(String logLevel) {
if (logLevel == null || logLevel.isEmpty()) {
return defaultLogLevel;
}
for(QBLogLevel level : QBLogLevel.values()) {
for (QBLogLevel level : QBLogLevel.values()) {
if (level.toString().equalsIgnoreCase(logLevel))
return level;
}
Expand Down
48 changes: 48 additions & 0 deletions example/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,39 @@ class App extends PureComponent {
exp.forEach(e => console.log(e));
};

getPlacement = async () => {
const placement = await QubitSDK.getPlacement(
"tsOujouCSSKJGSCMUsmQRw",
"LIVE",
null,
"1ybrhki9RvKWpA-9veLQSg",
null
);
console.log(placement);
};

sendPlacementImpression = async () => {
const placement = await QubitSDK.getPlacement(
"tsOujouCSSKJGSCMUsmQRw",
"LIVE",
null,
"1ybrhki9RvKWpA-9veLQSg",
null
);
placement.impression();
};

sendPlacementClickthrough = async () => {
const placement = await QubitSDK.getPlacement(
"tsOujouCSSKJGSCMUsmQRw",
"LIVE",
null,
"1ybrhki9RvKWpA-9veLQSg",
null
);
placement.clickthrough();
};

render() {
return (
<>
Expand Down Expand Up @@ -82,6 +115,21 @@ class App extends PureComponent {
Get experiences
</Text>
</TouchableOpacity>
<TouchableOpacity onPress={this.getPlacement}>
<Text>
Get placement
</Text>
</TouchableOpacity>
<TouchableOpacity onPress={this.sendPlacementImpression}>
<Text>
Send placement impression callback
</Text>
</TouchableOpacity>
<TouchableOpacity onPress={this.sendPlacementClickthrough}>
<Text>
Send placement clickthrough callback
</Text>
</TouchableOpacity>
</SafeAreaView>
</>
)
Expand Down
10 changes: 10 additions & 0 deletions ios/QubitSDKModule/QubitSDKModule.m
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,15 @@ @interface RCT_EXTERN_REMAP_MODULE(QubitSDK, QubitSDKModule, NSObject)
resolver:(RCTPromiseResolveBlock) resolver
rejecter:(RCTPromiseRejectBlock) rejecter)
RCT_EXTERN_METHOD(experienceShown:(NSString *) callback)
RCT_EXTERN_METHOD(getPlacement:
(NSString *) placementId
mode:(NSString *) mode
attributes:(NSString *) attributes
campaignId:(NSString *) campaignId
experienceId:(NSString *) experienceId
resolver:(RCTPromiseResolveBlock) resolver
rejecter:(RCTPromiseRejectBlock) rejecter)
RCT_EXTERN_METHOD(placementImpression:(NSString *) callback)
RCT_EXTERN_METHOD(placementClickthrough:(NSString *) callback)

@end
Loading