Skip to content
Merged
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
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,12 @@ const YourApp = () => {

## Contributing

See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow.
See the [contributing guide](docs/CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow.

## Integration with Sourcepoint SDK

See the [Sourcepoint SDK documentation](./docs/SOURCEPOINT.md) for information on integrating the Contentpass SDK with the Sourcepoint SDK.


## License

Expand Down
File renamed without changes.
File renamed without changes.
126 changes: 126 additions & 0 deletions docs/SOURCEPOINT_SDK_INTEGRATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# Integration with Sourcepoint SDK
The Contentpass SDK can be seamlessly integrated with the Sourcepoint SDK to manage consent. Since the Sourcepoint SDK
is a separate React Native package, you must install it independently. For detailed guidance, refer to the
[Sourcepoint SDK documentation](https://github.com/SourcePointUSA/react-native-sourcepoint-cmp).


## Setting Up Sourcepoint
To use the Sourcepoint SDK, follow these steps:

1. Create a Sourcepoint Account: Set up a Sourcepoint account and create a property with the type APP.
2. Configure the Property, ensure the property includes:
- Campaigns
- Partition Sets
- Scenarios (with the `acps` parameter — see [here](https://docs.contentpass.net/docs/onboarding/cmp/sourcepoint#4-sourcepoint-contentpass-integration) for details)
- Messages

For more information, consult the [Sourcepoint documentation](https://docs.sourcepoint.com/hc/en-us).

A newly created property should resemble the following example:
![sourcepoint-property-example.png](./assets/sourcepoint-property-example.png)

### Adding a Custom Action to Sourcepoint Messages
To integrate the Sourcepoint SDK with the Contentpass SDK, you must define a custom action in Sourcepoint Messages:
1. Navigate to `Messages` > `GDPR Messages` > `Web / Webview (TCF)`.
2. Edit the relevant message and add a custom action to the login button, such as `cp('login')`.
3. This custom action will authenticate users through the Contentpass SDK.

Example configuration:
![sourcepoint-button-config.png](./assets/sourcepoint-button-config.png)

## Code Integration
After setting up Sourcepoint, install its SDK package. Use the following code to integrate Contentpass and Sourcepoint
SDKs in your app.

### Important note
After creating a property in Sourcepoint, you must wait approximately 15 minutes before it becomes available for use
with the `@sourcepoint/react-native-cmp package`. This delay allows the configuration to propagate.

### Implementation
Install the Sourcepoint SDK package, then use the following code to integrate the two SDKs in your app:

```jsx
import { useEffect, useRef, useState } from 'react';
import { SPConsentManager } from '@sourcepoint/react-native-cmp';
import { ContentpassStateType, useContentpassSdk } from '@contentpass/react-native-contentpass';

const sourcePointConfig = {
accountId: 'SOURCEPOINT_ACCOUNT_ID',
propertyId: 'SOURCEPOINT_PROPERTY_ID',
propertyName: 'SOURCEPOINT_PROPERTY_NAME',
};

const setupSourcepoint = (hasValidSubscription) => {
const { accountId, propertyName, propertyId } = sourcePointConfig;
const spConsentManager = new SPConsentManager();

spConsentManager.build(accountId, propertyId, propertyName, {
gdpr: {
targetingParams: {
acps: hasValidSubscription ? 'true' : 'false',
},
},
});

return spConsentManager;
};

const App = () => {
const [authResult, setAuthResult] = useState();
const contentpassSdk = useContentpassSdk();
const spConsentManager = useRef();

useEffect(() => {
const onContentpassStateChange = (state) => {
setAuthResult(state);
};

contentpassSdk.registerObserver(onContentpassStateChange);

return () => {
contentpassSdk.unregisterObserver(onContentpassStateChange);
};
}, [contentpassSdk]);

useEffect(() => {
// wait for the authResult to be set before setting up Sourcepoint
if (!authResult || authResult.state === ContentpassStateType.INITIALISING) {
return;
}

spConsentManager.current = setupSourcepoint(
authResult?.hasValidSubscription ?? false
);

spConsentManager.current?.onAction((action) => {
if (action.customActionId === "cp('login')") {
contentpassSdk.authenticate()
}
});

spConsentManager.current?.loadMessage();

return () => {
spConsentManager.current?.dispose();
};
}, [authResult, contentpassSdk]);

return (
// Your app content
)
}
```

## Troubleshooting
While integrating the Contentpass SDK with Sourcepoint SDK (version `0.3.0`), you may encounter known issues. Pull requests
addressing these issues have been submitted in the [Sourcepoint GitHub repository](https://github.com/SourcePointUSA/react-native-sourcepoint-cmp):
- [PR #10](https://github.com/SourcePointUSA/react-native-sourcepoint-cmp/pull/10)
- [PR #11](https://github.com/SourcePointUSA/react-native-sourcepoint-cmp/pull/11)

### Temporary Fixes
If these fixes are not yet available in the latest version of the SDK, you can patch node_modules in your project using
tools like `yarn patch` or similar. The patch files can be found here:
- Patch for [PR #10](https://github.com/SourcePointUSA/react-native-sourcepoint-cmp/pull/10): [@sourcepoint-react-native-cmp-npm-0.3.0-2434c31dc9.patch](./sourcepoint-patches/@sourcepoint-react-native-cmp-npm-0.3.0-2434c31dc9.patch)
- Patch for [PR #11](https://github.com/SourcePointUSA/react-native-sourcepoint-cmp/pull/11): (https://github.com/SourcePointUSA/react-native-sourcepoint-cmp/pull/11): [@sourcepoint-react-native-cmp-patch-34fca36663.patch](./sourcepoint-patches/@sourcepoint-react-native-cmp-patch-34fca36663.patch)

We hope these issues will be resolved in the next release of the Sourcepoint SDK, eliminating the need for manual patches.
Binary file added docs/assets/sourcepoint-button-config.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/sourcepoint-property-example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
diff --git a/android/src/main/java/com/sourcepoint/reactnativecmp/RNSourcepointCmpModule.kt b/android/src/main/java/com/sourcepoint/reactnativecmp/RNSourcepointCmpModule.kt
index deb04fb18dbd8adffcb225801ad35b3154a3c7ad..4d372d921cbae6163179435feb9c821e3c37134b 100644
--- a/android/src/main/java/com/sourcepoint/reactnativecmp/RNSourcepointCmpModule.kt
+++ b/android/src/main/java/com/sourcepoint/reactnativecmp/RNSourcepointCmpModule.kt
@@ -119,6 +119,7 @@ class RNSourcepointCmpModule internal constructor(context: ReactApplicationConte
override fun onAction(view: View, consentAction: ConsentAction): ConsentAction {
sendEvent(SDKEvent.onAction, createMap().apply {
putString("actionType", RNSourcepointActionType.from(consentAction.actionType).name)
+ putString("customActionId", consentAction.customActionId ?: "")
})
return consentAction
}
diff --git a/ios/RNSourcepointCmp.swift b/ios/RNSourcepointCmp.swift
index 556b56618c847ad8aeaf9cdc680813cc26b732a9..ba7d707232d72fe5038ec05fb6fdb8e27216e4ee 100644
--- a/ios/RNSourcepointCmp.swift
+++ b/ios/RNSourcepointCmp.swift
@@ -69,7 +69,10 @@ extension RNSourcepointCmp: SPDelegate {
func onAction(_ action: SPAction, from controller: UIViewController) {
RNSourcepointCmp.shared?.sendEvent(
withName: "onAction",
- body: ["actionType": RNSourcepointActionType(from: action.type).rawValue]
+ body: [
+ "actionType": RNSourcepointActionType(from: action.type).rawValue,
+ "customActionId": action.customActionId ?? "",
+ ]
)
}

diff --git a/lib/typescript/src/index.d.ts b/lib/typescript/src/index.d.ts
index 1602516717becd5ec0a8e5036ad2d821110af96f..67bb9e5153b7489c5ead4dcd056b502b71bc2a7d 100644
--- a/lib/typescript/src/index.d.ts
+++ b/lib/typescript/src/index.d.ts
@@ -12,6 +12,7 @@ export declare class SPConsentManager implements Spec {
loadUSNatPrivacyManager(pmId: string): void;
onAction(callback: (body: {
actionType: SPActionType;
+ customActionId: string;
}) => void): void;
onSPUIReady(callback: () => void): void;
onSPUIFinished(callback: () => void): void;
diff --git a/lib/typescript/src/types.d.ts b/lib/typescript/src/types.d.ts
index a15f7a06c3e0635168987a44a33009ff42bbd31c..a035a72af14f32adf0ff88f959eb8c517ffaea47 100644
--- a/lib/typescript/src/types.d.ts
+++ b/lib/typescript/src/types.d.ts
@@ -86,6 +86,7 @@ export interface Spec extends TurboModule {
loadUSNatPrivacyManager(pmId: string): void;
onAction(callback: (body: {
actionType: SPActionType;
+ customActionId: string;
}) => void): void;
onSPUIReady(callback: () => void): void;
onSPUIFinished(callback: () => void): void;
diff --git a/src/index.ts b/src/index.ts
index b3e76b15572c56f1a4e54068b90243d6dd028e18..a03d87fea4a93edb6bf904c99d32b029b840bade 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -67,7 +67,7 @@ export class SPConsentManager implements Spec {
RNSourcepointCmp.loadUSNatPrivacyManager(pmId);
}

- onAction(callback: (body: { actionType: SPActionType }) => void): void {
+ onAction(callback: (body: { actionType: SPActionType, customActionId: string }) => void): void {
this.emitter.removeAllListeners('onAction');
this.emitter.addListener('onAction', callback);
}
diff --git a/src/types.ts b/src/types.ts
index 26ac3d8162c0534af98e2a20d237856195fe5a10..4257aff5ed128988c7d3fba60545672966162b20 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -113,7 +113,7 @@ export interface Spec extends TurboModule {
loadGDPRPrivacyManager(pmId: string): void;
loadUSNatPrivacyManager(pmId: string): void;

- onAction(callback: (body: { actionType: SPActionType }) => void): void;
+ onAction(callback: (body: { actionType: SPActionType, customActionId: string }) => void): void;
onSPUIReady(callback: () => void): void;
onSPUIFinished(callback: () => void): void;
onFinished(callback: () => void): void;
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
diff --git a/android/src/main/java/com/sourcepoint/reactnativecmp/RNSourcepointCmpTypes.kt b/android/src/main/java/com/sourcepoint/reactnativecmp/RNSourcepointCmpTypes.kt
index bb8c6c37adc3d7980c7e92268b98b9d97ef8de40..3d67b3a3f44743c4542a1966e66e1af3ea93c555 100644
--- a/android/src/main/java/com/sourcepoint/reactnativecmp/RNSourcepointCmpTypes.kt
+++ b/android/src/main/java/com/sourcepoint/reactnativecmp/RNSourcepointCmpTypes.kt
@@ -16,7 +16,7 @@ data class SPCampaign(
val rawTargetingParam: ReadableMap?,
val supportLegacyUSPString: Boolean
) {
- val targetingParams = rawTargetingParam?.toHashMap()?.map { TargetingParam(it.key, it.toString()) } ?: emptyList()
+ val targetingParams = rawTargetingParam?.toHashMap()?.map { TargetingParam(it.key, it.value.toString()) } ?: emptyList()
}

data class SPCampaigns(
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"android",
"ios",
"cpp",
"docs",
"*.podspec",
"!ios/build",
"!android/build",
Expand Down