@blux.ai/web-sdk 1.3.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/README.md +46 -31
  2. package/dist/package.json +1 -1
  3. package/dist/src/BluxClient.d.ts +25 -15
  4. package/dist/src/BluxClient.js +150 -49
  5. package/dist/src/BluxClient.js.map +1 -1
  6. package/dist/src/apis/APIs.d.ts +385 -92
  7. package/dist/src/apis/APIs.js +51 -0
  8. package/dist/src/apis/APIs.js.map +1 -1
  9. package/dist/src/apis/createCrmEvent.d.ts +4 -0
  10. package/dist/src/apis/createCrmEvent.js +7 -0
  11. package/dist/src/apis/createCrmEvent.js.map +1 -0
  12. package/dist/src/apis/createEvent.d.ts +1 -1
  13. package/dist/src/apis/createEvent.js.map +1 -1
  14. package/dist/src/apis/getItemRecommendations.d.ts +1 -1
  15. package/dist/src/apis/getItemRecommendations.js.map +1 -1
  16. package/dist/src/apis/inappsDispatch.d.ts +5 -0
  17. package/dist/src/apis/inappsDispatch.js +7 -0
  18. package/dist/src/apis/inappsDispatch.js.map +1 -0
  19. package/dist/src/apis/initialize.d.ts +1 -1
  20. package/dist/src/apis/initialize.js.map +1 -1
  21. package/dist/src/apis/signIn.d.ts +1 -1
  22. package/dist/src/apis/signIn.js.map +1 -1
  23. package/dist/src/apis/signOut.d.ts +1 -1
  24. package/dist/src/apis/signOut.js.map +1 -1
  25. package/dist/src/apis/updateCustomUserProperties.d.ts +1 -1
  26. package/dist/src/apis/updateCustomUserProperties.js.map +1 -1
  27. package/dist/src/apis/updateUserProperties.d.ts +1 -1
  28. package/dist/src/apis/updateUserProperties.js.map +1 -1
  29. package/dist/src/events/AddCartaddEvent.d.ts +2 -2
  30. package/dist/src/events/AddCartaddEvent.js +3 -3
  31. package/dist/src/events/AddCartaddEvent.js.map +1 -1
  32. package/dist/src/events/AddClickEvent.d.ts +2 -2
  33. package/dist/src/events/AddClickEvent.js +3 -3
  34. package/dist/src/events/AddClickEvent.js.map +1 -1
  35. package/dist/src/events/AddCustomEvent.d.ts +2 -2
  36. package/dist/src/events/AddCustomEvent.js +4 -4
  37. package/dist/src/events/AddCustomEvent.js.map +1 -1
  38. package/dist/src/events/AddInstantImpressionEvent.d.ts +2 -2
  39. package/dist/src/events/AddInstantImpressionEvent.js +3 -3
  40. package/dist/src/events/AddInstantImpressionEvent.js.map +1 -1
  41. package/dist/src/events/AddLikeEvent.d.ts +2 -2
  42. package/dist/src/events/AddLikeEvent.js +3 -3
  43. package/dist/src/events/AddLikeEvent.js.map +1 -1
  44. package/dist/src/events/AddOrderEvent.d.ts +5 -0
  45. package/dist/src/events/AddOrderEvent.js +16 -0
  46. package/dist/src/events/AddOrderEvent.js.map +1 -0
  47. package/dist/src/events/AddPageViewEvent.d.ts +2 -2
  48. package/dist/src/events/AddPageViewEvent.js +2 -2
  49. package/dist/src/events/AddPageViewEvent.js.map +1 -1
  50. package/dist/src/events/AddPageVisitEvent.d.ts +2 -2
  51. package/dist/src/events/AddPageVisitEvent.js +2 -2
  52. package/dist/src/events/AddPageVisitEvent.js.map +1 -1
  53. package/dist/src/events/AddPersistentImpressionEvent.d.ts +2 -2
  54. package/dist/src/events/AddPersistentImpressionEvent.js +3 -3
  55. package/dist/src/events/AddPersistentImpressionEvent.js.map +1 -1
  56. package/dist/src/events/AddProductDetailViewEvent.d.ts +2 -2
  57. package/dist/src/events/AddProductDetailViewEvent.js +3 -3
  58. package/dist/src/events/AddProductDetailViewEvent.js.map +1 -1
  59. package/dist/src/events/AddRateEvent.d.ts +2 -2
  60. package/dist/src/events/AddRateEvent.js +3 -3
  61. package/dist/src/events/AddRateEvent.js.map +1 -1
  62. package/dist/src/events/AddSearchEvent.d.ts +2 -2
  63. package/dist/src/events/AddSearchEvent.js +3 -3
  64. package/dist/src/events/AddSearchEvent.js.map +1 -1
  65. package/dist/src/events/AddSectionViewEvent.d.ts +2 -2
  66. package/dist/src/events/AddSectionViewEvent.js +2 -2
  67. package/dist/src/events/AddSectionViewEvent.js.map +1 -1
  68. package/dist/src/events/Event.d.ts +1 -0
  69. package/dist/src/events/Event.js +1 -0
  70. package/dist/src/events/Event.js.map +1 -1
  71. package/dist/src/events/VisitEvent.d.ts +2 -2
  72. package/dist/src/events/VisitEvent.js +2 -2
  73. package/dist/src/events/VisitEvent.js.map +1 -1
  74. package/dist/src/events/index.d.ts +1 -1
  75. package/dist/src/events/index.js +1 -1
  76. package/dist/src/events/index.js.map +1 -1
  77. package/dist/src/events/types.d.ts +26 -15
  78. package/dist/src/events/types.js.map +1 -1
  79. package/dist/src/recs/ItemRec.js.map +1 -1
  80. package/dist/src/utils/LocalStorage.d.ts +2 -0
  81. package/dist/src/utils/LocalStorage.js +8 -1
  82. package/dist/src/utils/LocalStorage.js.map +1 -1
  83. package/dist/src/utils/Logger.js +0 -1
  84. package/dist/src/utils/Logger.js.map +1 -1
  85. package/dist/src/utils/SessionStorage.js +0 -1
  86. package/dist/src/utils/SessionStorage.js.map +1 -1
  87. package/dist/src/utils/operators.js +0 -1
  88. package/dist/src/utils/operators.js.map +1 -1
  89. package/dist/src/utils/zodSchemas.d.ts +27 -27
  90. package/dist/src/utils/zodSchemas.js +2 -2
  91. package/dist/src/utils/zodSchemas.js.map +1 -1
  92. package/dist/tsconfig.tsbuildinfo +1 -1
  93. package/package.json +1 -1
  94. package/dist/src/events/AddPurchaseEvent.d.ts +0 -5
  95. package/dist/src/events/AddPurchaseEvent.js +0 -16
  96. package/dist/src/events/AddPurchaseEvent.js.map +0 -1
package/README.md CHANGED
@@ -17,12 +17,12 @@ yarn add @blux.ai/web-sdk
17
17
 
18
18
  ---
19
19
 
20
- - 필요 변수 : `클라이언트 ID`, `API 키`
20
+ - 필요 변수 : `Application ID`, `API 키`
21
21
 
22
22
  ```typescript
23
23
  const bluxClient = new BluxClient({
24
- applicationId: "{blux_client_id}",
25
- bluxApiKey: "{blux_api_key}",
24
+ bluxApplicationId: "BLUX_APPLICATION_ID",
25
+ bluxAPIKey: "BLUX_API_KEY",
26
26
  });
27
27
  bluxClient.setLogLevel("warning");
28
28
  ```
@@ -42,7 +42,7 @@ bluxClient.setLogLevel("warning");
42
42
  - 회원 유저가 앱을 실행하는 시점에도 `initialize` 메소드 호출 이후에 실행되어야 합니다.
43
43
 
44
44
  ```typescript
45
- bluxClient.signIn("USER ID");
45
+ bluxClient.signIn({ userId: "USER ID" });
46
46
  ```
47
47
 
48
48
  ### setUserProperties
@@ -51,8 +51,10 @@ bluxClient.signIn("USER ID");
51
51
 
52
52
  ```typescript
53
53
  bluxClient.setUserProperties({
54
- phone_number: "01011112222",
55
- email_address: "test@example.com",
54
+ userProperties: {
55
+ phone_number: "01011112222",
56
+ email_address: "test@example.com",
57
+ },
56
58
  });
57
59
  ```
58
60
 
@@ -62,10 +64,11 @@ bluxClient.setUserProperties({
62
64
 
63
65
  ```typescript
64
66
  bluxClient.setCustomUserProperties({
65
- custom_key1: "any_value",
66
- custom_key2: true,
67
- custom_key3: null,
68
- custom_key4: 3,
67
+ customUserProperties: {
68
+ custom_key1: "any_value",
69
+ custom_key2: true,
70
+ custom_key4: 3,
71
+ },
69
72
  });
70
73
  ```
71
74
 
@@ -89,7 +92,7 @@ bluxClient.signOut();
89
92
  ```typescript
90
93
  bluxClient.sendEvent(
91
94
  new AddProductDetailViewEvent({
92
- item_id: "ITEM_ID",
95
+ itemId: "ITEM_ID",
93
96
  }),
94
97
  );
95
98
  ```
@@ -103,7 +106,7 @@ bluxClient.sendEvent(
103
106
  ```typescript
104
107
  bluxClient.sendEvent(
105
108
  new AddLikeEvent({
106
- item_id: "ITEM_ID",
109
+ itemId: "ITEM_ID",
107
110
  }),
108
111
  );
109
112
  ```
@@ -117,41 +120,53 @@ bluxClient.sendEvent(
117
120
  ```typescript
118
121
  bluxClient.sendEvent(
119
122
  new AddCartaddEvent({
120
- item_id: "ITEM_ID",
123
+ itemId: "ITEM_ID",
121
124
  }),
122
125
  );
123
126
  ```
124
127
 
125
128
  #### 상품 구매
126
129
 
127
- : 유저가 제품을 구매했을 때 사용 가능한 이벤트입니다. 추가 인풋으로 `price`가 요구되며, 제품의 구매 당시 가격을 기록하면 됩니다.
130
+ : 유저가 제품을 구매했을 때 사용 가능한 이벤트입니다. paidAmount 파라미터의 경우, 캠페인을 통한 성과 집계에 사용되는 값입니다.
128
131
 
129
132
  ---
130
133
 
131
- - **_동일 상품 복수 구매_**
132
- - price 파라미터의 경우, 해당 상품 판매를 통한 총 매출을 계산할 때 활용됩니다. 추천에 의한 매출 기여액 지표를 보여드릴 때 사용되는 값으로 만약 5,000원짜리 상품을 5개 구매하였다면, 25,000 을 입력하시면 됩니다.
133
- - **_복수 상품 구매_**
134
- - `AddPurchaseEvent` 객체를 각 상품 구매건에 맞춰서 생성한 후 list 형태로 넘겨주시면 됩니다.
135
-
136
134
  ```typescript
137
135
  bluxClient.sendEvent(
138
- new AddPurchaseEvent({
139
- item_id: "ITEM_ID",
140
- price: 1000,
136
+ new AddOrderEvent({
137
+ orderId: "ORDER_ID",
138
+ paidAmount: 1200,
139
+ orderAmount: 2000,
140
+ items: [
141
+ {
142
+ id: "ITEM_ID_1",
143
+ price: 1000,
144
+ quantity: 1,
145
+ },
146
+ ],
141
147
  }),
142
148
  );
143
149
  ```
144
150
 
145
151
  ```typescript
146
152
  // 복수 상품을 구매한 경우
147
- bluxClient.sendEvent([
148
- new AddPurchaseEvent({
149
- item_id: "ITEM_ID_1",
150
- price: 1000,
151
- }),
152
- new AddPurchaseEvent({
153
- item_id: "ITEM_ID_2",
154
- price: 2000,
153
+ bluxClient.sendEvent(
154
+ new AddOrderEvent({
155
+ orderId: "ORDER_ID",
156
+ paidAmount: 1200,
157
+ orderAmount: 2000,
158
+ items: [
159
+ {
160
+ id: "ITEM_ID_1",
161
+ price: 1000,
162
+ quantity: 1,
163
+ },
164
+ {
165
+ id: "ITEM_ID_2",
166
+ price: 2000,
167
+ quantity: 2,
168
+ },
169
+ ],
155
170
  }),
156
- ]);
171
+ );
157
172
  ```
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blux.ai/web-sdk",
3
- "version": "1.3.0",
3
+ "version": "2.0.0",
4
4
  "description": "The official Blux JavaScript browser client library",
5
5
  "main": "dist/src/index.js",
6
6
  "module": "dist/src/index.js",
@@ -1,16 +1,16 @@
1
1
  import { BehaviorSubject } from "rxjs";
2
- import type { LogLevel } from "./utils/Logger";
3
- import type { EventRequest } from "./events/types";
2
+ import { DevicePlatform, type APIs } from "./apis/APIs";
4
3
  import type { Event as BluxEvent } from "./events/Event";
5
- import { type APIs } from "./apis/APIs";
4
+ import type { EventRequest } from "./events/types";
6
5
  import type { CategoryRec, ItemRec, ItemsRec, UserRec } from "./recs";
6
+ import type { LogLevel } from "./utils/Logger";
7
7
  export type SdkInfo = {
8
- type: string;
8
+ type: DevicePlatform;
9
9
  version: string;
10
10
  };
11
11
  type BluxUser = {
12
12
  id: string;
13
- bluxApiKey: string;
13
+ bluxAPIKey: string;
14
14
  applicationId: string;
15
15
  deviceId?: string;
16
16
  userId?: string;
@@ -20,31 +20,41 @@ export declare class BluxClient {
20
20
  private readonly sdkInfo;
21
21
  readonly bluxUser$: BehaviorSubject<BluxUser | undefined>;
22
22
  readonly requestQueue$: BehaviorSubject<EventRequest[]>;
23
- private readonly applicationId;
24
- private readonly bluxApiKey;
23
+ readonly inappQueue$: BehaviorSubject<APIs.inappsDispatcher.ResponseData | undefined>;
24
+ private readonly bluxApplicationId;
25
+ private readonly bluxAPIKey;
25
26
  private impressedElements;
26
27
  private intersectionObservingElements;
27
28
  private readonly intersectionObserver;
28
29
  private readonly intersectionEntry$;
29
30
  private hitElements;
30
- constructor({ applicationId, bluxApiKey, }: {
31
- applicationId: string;
32
- bluxApiKey: string;
31
+ constructor({ bluxApplicationId, bluxAPIKey, }: {
32
+ bluxApplicationId: string;
33
+ bluxAPIKey: string;
33
34
  }, completionCallback?: (args: {
34
35
  errorMessage?: string;
35
36
  success: boolean;
36
37
  }) => void);
37
38
  private generateApiHeader;
39
+ private handleSendRequest;
40
+ private handleInappEvent;
41
+ private displayInapp;
38
42
  private init;
39
43
  setLogLevel(logLevel: LogLevel): void;
40
44
  private getBluxUserWithTimeout;
41
- signIn(userId: string): Promise<void>;
45
+ signIn({ userId }: {
46
+ userId: string;
47
+ }): Promise<void>;
42
48
  signOut(): Promise<void>;
43
- setUserProperties(userProperties: {
44
- phone_number?: string;
45
- email_address?: string;
49
+ setUserProperties({ userProperties, }: {
50
+ userProperties: {
51
+ phone_number?: string;
52
+ email_address?: string;
53
+ };
54
+ }): Promise<void>;
55
+ setCustomUserProperties({ customUserProperties, }: {
56
+ customUserProperties: Record<string, string | boolean | number | null>;
46
57
  }): Promise<void>;
47
- setCustomUserProperties(customUserProperties: Record<string, string | boolean | number | null>): Promise<void>;
48
58
  sendEvent(event: BluxEvent | BluxEvent[]): void;
49
59
  private urlAndRef$;
50
60
  private handleUrlAndRef;
@@ -1,32 +1,36 @@
1
- import packageJson from "../package.json";
2
- import { asyncScheduler, BehaviorSubject, catchError, combineLatest, debounceTime, exhaustMap, filter, firstValueFrom, groupBy, map, mergeMap, observeOn, Subject, throwError, timeout, } from "rxjs";
3
- import { LocalStorage } from "./utils/LocalStorage";
4
- import { Logger } from "./utils/Logger";
5
1
  import axios from "axios";
6
- import { filterNullable } from "./utils/operators";
2
+ import dayjs from "dayjs";
3
+ import { asyncScheduler, BehaviorSubject, catchError, combineLatest, concatMap, debounceTime, exhaustMap, filter, firstValueFrom, from, groupBy, map, mergeMap, observeOn, Subject, throwError, timeout, } from "rxjs";
4
+ import packageJson from "../package.json";
5
+ import { DevicePlatform } from "./apis/APIs";
6
+ import { createCrmEvent } from "./apis/createCrmEvent";
7
+ import { collectEvent } from "./apis/createEvent";
8
+ import { getItemRecommendations } from "./apis/getItemRecommendations";
9
+ import { inappsDispatch } from "./apis/inappsDispatch";
7
10
  import { initialize } from "./apis/initialize";
8
11
  import { signIn } from "./apis/signIn";
9
12
  import { signOut } from "./apis/signOut";
10
- import { updateUserProperties } from "./apis/updateUserProperties";
11
13
  import { updateCustomUserProperties } from "./apis/updateCustomUserProperties";
12
- import { collectEvent } from "./apis/createEvent";
13
- import { DevicePlatform } from "./apis/APIs";
14
- import { SessionStorage } from "./utils/SessionStorage";
15
- import { AddClickEvent, AddPageVisitEvent, AddSectionViewEvent, VisitEvent, } from "./events";
14
+ import { updateUserProperties } from "./apis/updateUserProperties";
16
15
  import { BLUX_ATTRIBUTES } from "./constants/BLUX_ATTRIBUTES";
17
- import { getItemRecommendations } from "./apis/getItemRecommendations";
16
+ import { AddClickEvent, AddPageVisitEvent, AddSectionViewEvent, VisitEvent, } from "./events";
17
+ import { LocalStorage } from "./utils/LocalStorage";
18
+ import { Logger } from "./utils/Logger";
19
+ import { filterNullable } from "./utils/operators";
20
+ import { SessionStorage } from "./utils/SessionStorage";
18
21
  export class BluxClient {
19
22
  api = axios.create({
20
23
  baseURL: "https://api.blux.ai/prod",
21
24
  });
22
25
  sdkInfo = {
23
- type: "browser",
26
+ type: DevicePlatform.browser,
24
27
  version: packageJson.version,
25
28
  };
26
29
  bluxUser$ = new BehaviorSubject(undefined);
27
30
  requestQueue$ = new BehaviorSubject([]);
28
- applicationId;
29
- bluxApiKey;
31
+ inappQueue$ = new BehaviorSubject(undefined);
32
+ bluxApplicationId;
33
+ bluxAPIKey;
30
34
  // Impression 관련 변수
31
35
  impressedElements = [];
32
36
  intersectionObservingElements = [];
@@ -38,32 +42,25 @@ export class BluxClient {
38
42
  intersectionEntry$ = new Subject();
39
43
  // Hit 관련 변수
40
44
  hitElements = [];
41
- constructor({ applicationId, bluxApiKey, }, completionCallback) {
42
- this.applicationId = applicationId;
43
- this.bluxApiKey = bluxApiKey;
45
+ constructor({ bluxApplicationId, bluxAPIKey, }, completionCallback) {
46
+ this.bluxApplicationId = bluxApplicationId;
47
+ this.bluxAPIKey = bluxAPIKey;
44
48
  combineLatest([this.requestQueue$, this.bluxUser$.pipe(filterNullable())])
45
49
  .pipe(filter(([requests]) => requests.length > 0), exhaustMap(async ([requests, bluxUser]) => {
46
- try {
47
- await collectEvent(this.api, {
48
- blux_user_id: bluxUser.id,
49
- application_id: bluxUser.applicationId,
50
- }, {
51
- events: requests.map((request) => ({
52
- ...request,
53
- internal_event_properties: {
54
- ...request.internal_event_properties,
55
- url: `${this.urlAndRef$.value?.url ?? null}`,
56
- ref: `${this.urlAndRef$.value?.ref ?? null}`,
57
- },
58
- blux_id: bluxUser.id,
59
- device_id: bluxUser.deviceId,
60
- })),
61
- }, this.generateApiHeader(bluxUser));
62
- }
63
- catch (error) {
64
- // todo : retry
65
- Logger.error(error, { tags: { from: "request-events-api" } });
66
- }
50
+ const events = requests.map((request) => ({
51
+ ...request,
52
+ internal_event_properties: {
53
+ ...request.internal_event_properties,
54
+ url: `${this.urlAndRef$.value?.url ?? null}`,
55
+ ref: `${this.urlAndRef$.value?.ref ?? null}`,
56
+ },
57
+ blux_id: bluxUser.id,
58
+ device_id: bluxUser.deviceId,
59
+ }));
60
+ await Promise.allSettled([
61
+ this.handleSendRequest({ bluxUser, events }),
62
+ this.handleInappEvent(bluxUser, events),
63
+ ]);
67
64
  return requests.map((r) => r.id); // todo: return successed requests only
68
65
  }), map((requestIdsSucceeded) => this.requestQueue$.value.filter((request) => !requestIdsSucceeded.includes(request.id))), observeOn(asyncScheduler))
69
66
  .subscribe(this.requestQueue$);
@@ -71,6 +68,10 @@ export class BluxClient {
71
68
  if (bluxUser)
72
69
  SessionStorage.setBluxUserId(bluxUser.id);
73
70
  });
71
+ this.inappQueue$
72
+ .pipe(filterNullable())
73
+ .pipe(concatMap((inapp) => from(this.displayInapp(inapp))))
74
+ .subscribe();
74
75
  this.init()
75
76
  .then(() => {
76
77
  completionCallback?.({ success: true });
@@ -79,17 +80,117 @@ export class BluxClient {
79
80
  completionCallback?.({ success: false, errorMessage: error.message });
80
81
  });
81
82
  }
82
- generateApiHeader({ bluxApiKey }) {
83
+ generateApiHeader({ bluxAPIKey }) {
83
84
  return {
84
- Authorization: bluxApiKey,
85
+ Authorization: bluxAPIKey,
85
86
  };
86
87
  }
88
+ async handleSendRequest({ bluxUser, events, }) {
89
+ try {
90
+ await collectEvent(this.api, {
91
+ blux_user_id: bluxUser.id,
92
+ application_id: bluxUser.applicationId,
93
+ }, {
94
+ events,
95
+ }, this.generateApiHeader(bluxUser));
96
+ }
97
+ catch (error) {
98
+ Logger.error(error, { tags: { from: "request-events-api" } });
99
+ }
100
+ }
101
+ async handleInappEvent(bluxUser, events) {
102
+ try {
103
+ const { data } = await inappsDispatch(this.api, {
104
+ application_id: bluxUser.applicationId,
105
+ }, {
106
+ events,
107
+ blux_user_id: bluxUser.id,
108
+ device_id: bluxUser.deviceId ?? "",
109
+ platform: this.sdkInfo.type,
110
+ }, this.generateApiHeader(bluxUser));
111
+ this.inappQueue$.next(data);
112
+ }
113
+ catch (error) {
114
+ Logger.error(error, { tags: { from: "request-inapps-api" } });
115
+ }
116
+ }
117
+ async displayInapp(inapp) {
118
+ return new Promise((resolve) => {
119
+ if (!inapp.shouldDisplay)
120
+ return resolve(true);
121
+ const hideTimestamp = LocalStorage.getInappHideTimestamp(inapp.inappId);
122
+ const isShouldSkip = hideTimestamp !== null && dayjs().isBefore(dayjs(hideTimestamp));
123
+ if (isShouldSkip)
124
+ return resolve(true);
125
+ const iframeElement = document.createElement("iframe");
126
+ const params = new URLSearchParams({
127
+ inapp_id: inapp.inappId,
128
+ application_id: this.bluxApplicationId,
129
+ stage: "prod",
130
+ });
131
+ iframeElement.src = `${inapp.baseUrl}?${params.toString()}`;
132
+ iframeElement.style.position = "fixed";
133
+ iframeElement.style.width = `${window.innerWidth}px`;
134
+ iframeElement.style.height = `${window.innerHeight}px`;
135
+ iframeElement.style.top = "0";
136
+ iframeElement.style.left = "0";
137
+ iframeElement.style.zIndex = "9999";
138
+ iframeElement.id = `blux-inapp-${inapp.inappId}`;
139
+ document.body.appendChild(iframeElement);
140
+ const handleViewportChange = () => {
141
+ const width = window.visualViewport?.width ?? window.innerWidth;
142
+ const height = window.visualViewport?.height ?? window.innerHeight;
143
+ const left = window.visualViewport?.offsetLeft ?? 0;
144
+ const top = window.visualViewport?.offsetTop ?? 0;
145
+ iframeElement.style.width = `${width}px`;
146
+ iframeElement.style.height = `${height}px`;
147
+ iframeElement.style.left = `${left}px`;
148
+ iframeElement.style.top = `${top}px`;
149
+ };
150
+ const handleMessage = (event) => {
151
+ const message = event.data;
152
+ if (message.action === "hide") {
153
+ const { days_to_hide } = message.data;
154
+ if (days_to_hide !== 0) {
155
+ const expiresAt = dayjs().add(days_to_hide, "days").valueOf();
156
+ LocalStorage.setInappHideTimestamp(inapp.inappId, expiresAt);
157
+ }
158
+ }
159
+ else if (message.action === "link") {
160
+ const bluxUser = this.bluxUser$.getValue();
161
+ if (bluxUser) {
162
+ createCrmEvent(this.api, {
163
+ application_id: this.bluxApplicationId,
164
+ }, {
165
+ notification_id: inapp.notificationId,
166
+ crm_event_type: "inapp_opened",
167
+ captured_at: new Date().toISOString(),
168
+ }, this.generateApiHeader(bluxUser));
169
+ }
170
+ if (message.data.is_blux_landing) {
171
+ // TODO: 스키마상에는 개인화 랜딩이 존재하나, 콘솔에는 필드가 없음 -> 추후 이에 따른 핸들링이 필요함
172
+ }
173
+ else {
174
+ window.open(message.data.url, "_blank");
175
+ }
176
+ }
177
+ iframeElement.remove();
178
+ window.removeEventListener("message", handleMessage);
179
+ window.visualViewport?.removeEventListener("resize", handleViewportChange);
180
+ window.visualViewport?.removeEventListener("scroll", handleViewportChange);
181
+ resolve(inapp.inappId);
182
+ };
183
+ window.visualViewport?.addEventListener("resize", handleViewportChange);
184
+ window.visualViewport?.addEventListener("scroll", handleViewportChange);
185
+ window.addEventListener("message", handleMessage);
186
+ });
187
+ }
87
188
  async init() {
88
189
  const blux_user_id = new URLSearchParams(window.location.search).get("blux_user_id");
89
190
  const isBluxUserIdExistInSessionStorage = SessionStorage.getBluxUserId();
90
191
  if (!isBluxUserIdExistInSessionStorage)
91
192
  this.sendEvent(new VisitEvent({}));
92
- Logger.debug(`Init with application id: ${this.applicationId}`);
193
+ Logger.debug(`Init with application id: ${this.bluxApplicationId}`);
93
194
  const deviceId = LocalStorage.getDeviceId();
94
195
  if (!deviceId) {
95
196
  Logger.debug("No saved Device ID, register a new one.");
@@ -129,7 +230,7 @@ export class BluxClient {
129
230
  }));
130
231
  this.impressedElements.push(entry.target);
131
232
  });
132
- const { data } = await initialize(this.api, { application_id: this.applicationId }, {
233
+ const { data } = await initialize(this.api, { application_id: this.bluxApplicationId }, {
133
234
  isVisitHandlingInSdk: true,
134
235
  device_id: deviceId ?? undefined,
135
236
  country_code: navigator.language.split("-")[1],
@@ -142,14 +243,14 @@ export class BluxClient {
142
243
  timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
143
244
  blux_user_id: blux_user_id ?? undefined,
144
245
  }, this.generateApiHeader({
145
- bluxApiKey: this.bluxApiKey,
246
+ bluxAPIKey: this.bluxAPIKey,
146
247
  }));
147
248
  if (data.device_id)
148
249
  LocalStorage.setDeviceId(data.device_id);
149
250
  this.bluxUser$.next({
150
251
  id: data.blux_user_id,
151
- bluxApiKey: this.bluxApiKey,
152
- applicationId: this.applicationId,
252
+ bluxAPIKey: this.bluxAPIKey,
253
+ applicationId: this.bluxApplicationId,
153
254
  deviceId: data.device_id,
154
255
  });
155
256
  }
@@ -164,7 +265,7 @@ export class BluxClient {
164
265
  })));
165
266
  return bluxUser;
166
267
  }
167
- async signIn(userId) {
268
+ async signIn({ userId }) {
168
269
  try {
169
270
  const bluxUser = await this.getBluxUserWithTimeout();
170
271
  const { data: { blux_user_id: bluxIdInResponse }, } = await signIn(this.api, { application_id: bluxUser.applicationId, blux_user_id: bluxUser.id }, { user_id: userId, device_id: bluxUser.deviceId }, this.generateApiHeader(bluxUser));
@@ -194,7 +295,7 @@ export class BluxClient {
194
295
  Logger.error(error, { tags: { from: "signOut" } });
195
296
  }
196
297
  }
197
- async setUserProperties(userProperties) {
298
+ async setUserProperties({ userProperties, }) {
198
299
  try {
199
300
  const bluxUser = await this.getBluxUserWithTimeout();
200
301
  await updateUserProperties(this.api, { application_id: bluxUser.applicationId, blux_user_id: bluxUser.id }, { properties: userProperties }, this.generateApiHeader(bluxUser));
@@ -203,7 +304,7 @@ export class BluxClient {
203
304
  Logger.error(error, { tags: { from: "setUserProperties" } });
204
305
  }
205
306
  }
206
- async setCustomUserProperties(customUserProperties) {
307
+ async setCustomUserProperties({ customUserProperties, }) {
207
308
  try {
208
309
  const bluxUser = await this.getBluxUserWithTimeout();
209
310
  await updateCustomUserProperties(this.api, { application_id: bluxUser.applicationId, blux_user_id: bluxUser.id }, { properties: customUserProperties }, this.generateApiHeader(bluxUser));
@@ -276,7 +377,7 @@ export class BluxClient {
276
377
  }
277
378
  if (!this.hitElements.includes(targetItemElement)) {
278
379
  this.sendEvent(new AddClickEvent({
279
- item_id: itemId,
380
+ itemId,
280
381
  tracking: {
281
382
  id: trackingId,
282
383
  type: "hit",