2段階のデータ統合
個人を特定できる情報(PII)は、しばしばRoktがキャンペーンの目標を達成するために必要とされます。たとえば、顧客のメールアドレスはPIIと見なされ、Roktがメールキャンペーンを配信するために必要不可欠です。これらの情報は「フルフィルメント属性」として知られています。Roktは、顧客のプライバシーを確保し、顧客の体験の品質を維持するために、2段階のデータ統合プロセスを設計しています。
2段階のデータ統合プロセスでは、Roktはハッシュ化されたメールアドレスを使用して顧客を識別し、最も関連性の高い体験を選択します。顧客がRoktのオファーに積極的に関与した場合、オファーを履行するために必要な属性を開示します。2段階のデータ統合プロセスにより、顧客に追加のセキュリティが提供される一方で、Roktは予想される機能の一部(たとえば、再訪問顧客へのオファーの抑制)を提供することができます。
2段階のデータ統合は、Web、iOS、Android、およびReact NativeのSDKで実装することができます。以下のコードは、さまざまな言語での基本的な統合プロセスを示しています:
- JavaScript
- Swift
- Objective-C
- Kotlin
- Java
- React
js
```js
const rawAttributes = {
country: "US",
};
const twoStepDataIntegrationAttributes = {
email: "john.smith@rokt.com",
};
const hashedAttributes = await launcher.hashAttributes(
twoStepDataIntegrationAttributes
);
const selection = await launcher.selectPlacements({
attributes: {
...rawAttributes,
...hashedAttributes,
},
});
selection.on("POSITIVE_ENGAGEMENT").subscribe(() => {
selection.setAttributes(twoStepDataIntegrationAttributes);
});
上記のコードは、IntegrationLauncher.hashAttributesを使用して履行属性をハッシュ化しています。Roktは、将来的に追加の属性もハッシュ化する必要がある場合や、より複雑なハッシュ化アルゴリズムをシームレスにサポートする場合に、このユーティリティメソッドの使用を推奨しています。
属性をハッシュ化する場合は、属性値を小文字に変換し、ハッシュ化する前に前後の空白をトリムすること、および属性名に sha256
を接尾辞として付けることを確認してください。
以下の例は、事前にハッシュ化された属性の使用方法を示しています。
const email = "john.smith@rokt.com ";
const emailsha256 =
"F6191D8D6A0F75CA7D237ED07CF8E461E72E5C7BB28D611DDF37E5908FDB632B";
const selection = await launcher.selectPlacements({
attributes: {
country: "US",
emailsha256: emailsha256,
},
});
selection.on("POSITIVE_ENGAGEMENT").subscribe(() => {
selection.setAttributes({
email: email,
});
});
import Rokt_Widget
class OrderConfirmationViewController: UIViewController {
...
// プレースメントを表示する必要がある場合にこの関数を呼び出します
func showWidget() {
let attributes = ["firstname": "Jenny",
"lastname": "Smith",
"emailsha256": "36f15652992f5c291ea233b930c8c435ee5a5fb115d25933e3266591d3f92f74",
"postcode": "90210",
"country": "US"]
Rokt.execute2step(viewName: "RoktExperience", attributes: attributes, onLoad: {
// Roktプレースメントがロードされたときのオプションのコールバック
}, onUnLoad: {
// Roktプレースメントがアンロードされたときのオプションのコールバック
}, onShouldShowLoadingIndicator: {
// ローディングインジケータを表示するためのオプションのコールバック
}, onShouldHideLoadingIndicator: {
// ローディングインジケータを非表示にするためのオプションのコールバック
}, onEvent: { eventType , eventHandler in
if eventType == .FirstPositiveEngagement {
eventHandler.setFulfillmentAttributes(attributes: ["email": "j.smith@example.com"])
}
}
)
}
}
#import <Rokt_Widget/Rokt_Widget-Swift.h>
...
// プレースメントを表示する必要がある場合にこの関数を呼び出します
- (void)showWidget {
NSDictionary *attributes = @{
@"firstname": @"Jenny",
@"lastname": @"Smith",
@"emailsha256": @"36f15652992f5c291ea233b930c8c435ee5a5fb115d25933e3266591d3f92f74",
@"postcode": @"90210",
@"country": @"US"
};
[Rokt execute2stepWithViewName: @"RoktExperience"
attributes:attributes
placements:placements
onLoad:^{
// Roktウィジェットがロードされたときのオプションのコールバック
} onUnLoad:^{
// Roktウィジェットがアンロードされたときのオプションのコールバック
} onShouldShowLoadingIndicator:^{
// ローディングインジケータを表示するためのオプションのコールバック
} onShouldHideLoadingIndicator:^{
// ローディングインジケータを非表示にするためのオプションのコールバック
} onEmbeddedSizeChange:^(NSString *selectedPlacement, CGFloat widgetHeight){
// ウィジェットの高さが変更されるたびに必要な選択されたプレースメントと高さを取得するためのオプションのコールバック
} onEvent:^(RoktEventType eventType, RoktEventHandler* eventHandler){
if(eventType == RoktEventTypeFirstPositiveEngagement){
[eventHandler setFulfillmentAttributesWithAttributes: @{
@"email" : @"j.smith@example.com"}];
}
}];
}
import com.rokt.roktsdk.Widget
import com.rokt.roktsdk.Rokt
class ConfirmationActivity : Activity() {
private val roktCalllback = object : Rokt.RoktCallback {
override fun onLoad() {
}
override fun onShouldShowLoadingIndicator() {
}
override fun onShouldHideLoadingIndicator() {
}
override fun onUnload(reason: Rokt.UnloadReasons) {
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
...
// 適切なコンシューマ属性を含める
val attributes = hashMapOf(
Pair("emailsha256", "36f15652992f5c291ea233b930c8c435ee5a5fb115d25933e3266591d3f92f74"),
Pair("firstname", "Jenny"),
Pair("lastname", "Smith"),
Pair("mobile", "(323) 867-5309"),
Pair("postcode", "90210"),
Pair("country", "US")
)
// ウィジェットのプレースホルダーとプレースメントの場所の構成をマッピングする
val widget = findViewById<Widget>(R.id.roktWidget)
val placeHolders = hashMapOf(
Pair("RoktEmbedded1", WeakReference(widget))
)
Rokt.execute2Step(pageIdentifier, attributes, this, placeholders, object : Rokt.RoktEventCallback {
override fun onEvent(eventType: Rokt.RoktEventType, roktEventHandler: Rokt.RoktEventHandler) {
if (eventType == Rokt.RoktEventType.FirstPositiveEngagement) {
roktEventHandler.setFulfillmentAttributes(mapOf("email" to "j.smith@example.com"))
}
}
})
...
}
}
import com.rokt.roktsdk.Widget;
import com.rokt.roktsdk.Rokt;
class ConfirmationActivity : Activity() {
private Rokt.RoktCallback roktCallback = new Rokt.RoktCallback() {
@Override
public void onLoad() {
}
@Override
public void onShouldShowLoadingIndicator() {
}
@Override
public void onShouldHideLoadingIndicator() {
}
@Override
public void onUnload(@NotNull Rokt.UnloadReasons unloadReasons) {
}
};
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
Map<String, String> attributes = new HashMap<String, String>();
attributes.put("emailsha256", "36f15652992f5c291ea233b930c8c435ee5a5fb115d25933e3266591d3f92f74");
attributes.put("firstname", "Jenny");
attributes.put("lastname", "Smith");
attributes.put("mobile", "(323) 867-5309");
attributes.put("postcode", "90210");
attributes.put("country", "US");
// Widget placeholder mapping the placeholder view with placement location configuration
Widget widget = findViewById(R.id.roktWidget);
Map<String, WeakReference<Widget>> placeHolders = new HashMap<>();
placeHolders.put("RoktEmbedded1", new WeakReference<>(widget));
Rokt.INSTANCE.execute2Step("test,", roktCallback, new Rokt.RoktEventCallback() {
@Override
public void onEvent(Rokt.RoktEventType roktEventType, Rokt.RoktEventHandler roktEventHandler) {
Map<String,String> attributes = new HashMap<String, String>();
attributes.put("email", "j.smith@example.com");
if (roktEventType == Rokt.RoktEventType.FirstPositiveEngagement){
roktEventHandler.setFulfillmentAttributes(attributes);
}
}
});
...
}
}
import {
Rokt,
RoktEventManager
}
from "@rokt/react-native-sdk";
const roktEventManager = new NativeEventEmitter(RoktEventManager);
//Subscribe to FirstPositiveResponse event.
subscription = roktEventManager.addListener(
'FirstPositiveResponse',
(x) => {
console.log("Widget OnFirstPositiveEvent Callback");
// Send unhashed email on first positive response
fullfilmentAttributes = {
email: "j.smith@example.com"
};
Rokt.setFulfillmentAttributes(fullfilmentAttributes);
}
);
onExecuteHandler = () => {
attributes = {
"emailsha256": "238afb9e862add7d56bbc4181b80fa32",
"firstname": "Jenny",
"lastname": "Smith",
"mobile": "(323) 867-5309",
"postcode": "90210",
"country": "US"
};
Rokt.execute2Step("RoktExperience", attributes, null, () => console.log("Placement Loaded"));
}
// Remove subscription
componentWillUnmount() {
this.subscription.remove();
}