Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add a bridge for getPlacement method #8

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
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)
ljazgar marked this conversation as resolved.
Show resolved Hide resolved

### 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
ljazgar marked this conversation as resolved.
Show resolved Hide resolved

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"
);
...
ljazgar marked this conversation as resolved.
Show resolved Hide resolved
placement.impression();
...
placement.clickthrough();
}

{
"content": { ... }
}
```
ljazgar marked this conversation as resolved.
Show resolved Hide resolved

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:1.5.0'
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
ljazgar marked this conversation as resolved.
Show resolved Hide resolved
public void placementImpression(String callbackUrl) {
QubitSDK.sendCallbackRequest(callbackUrl);
}

@ReactMethod
public void placementClickthrough(String callbackUrl) {
ljazgar marked this conversation as resolved.
Show resolved Hide resolved
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);
};

ljazgar marked this conversation as resolved.
Show resolved Hide resolved
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