@botonic/react 0.36.0 → 0.36.1-alpha.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.
- package/lib/cjs/webview-app.js +106 -61
- package/lib/cjs/webview-app.js.map +1 -1
- package/lib/esm/webview-app.js +106 -61
- package/lib/esm/webview-app.js.map +1 -1
- package/package.json +1 -1
- package/src/webview-app.tsx +125 -67
package/lib/cjs/webview-app.js
CHANGED
|
@@ -17,39 +17,73 @@ var WebviewUrlParams;
|
|
|
17
17
|
WebviewUrlParams["UserId"] = "user_id";
|
|
18
18
|
WebviewUrlParams["HubtypeApiUrl"] = "hubtype_api_url";
|
|
19
19
|
})(WebviewUrlParams || (WebviewUrlParams = {}));
|
|
20
|
+
const DEFAULT_HUBTYPE_API_URL = 'https://api.hubtype.com';
|
|
20
21
|
class App extends react_1.default.Component {
|
|
21
22
|
constructor(props) {
|
|
22
23
|
super(props);
|
|
24
|
+
this.hubtypeApiUrl = DEFAULT_HUBTYPE_API_URL;
|
|
23
25
|
this.url = new URL(window.location.href);
|
|
24
|
-
this.botId = this.url.searchParams.get(WebviewUrlParams.BotId);
|
|
25
|
-
this.userId = this.url.searchParams.get(WebviewUrlParams.UserId);
|
|
26
|
-
this.hubtypeApiUrl =
|
|
27
|
-
this.url.searchParams.get(WebviewUrlParams.HubtypeApiUrl) ||
|
|
28
|
-
'https://api.hubtype.com';
|
|
29
26
|
this.state = {
|
|
30
27
|
session: null,
|
|
31
28
|
params: {},
|
|
32
29
|
};
|
|
33
30
|
}
|
|
34
31
|
componentDidMount() {
|
|
32
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
33
|
+
yield this.initializeApp();
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
initializeApp() {
|
|
35
37
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
36
38
|
try {
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
this.
|
|
39
|
+
const botId = this.url.searchParams.get(WebviewUrlParams.BotId);
|
|
40
|
+
const chatId = this.url.searchParams.get(WebviewUrlParams.UserId);
|
|
41
|
+
const hubtypeApiUrl = this.url.searchParams.get(WebviewUrlParams.HubtypeApiUrl);
|
|
42
|
+
if (botId && chatId && hubtypeApiUrl) {
|
|
43
|
+
const session = yield this.getBotSessionContextFromExternalApi(hubtypeApiUrl, botId, chatId);
|
|
44
|
+
this.hubtypeApiUrl = hubtypeApiUrl;
|
|
45
|
+
this.setState({
|
|
46
|
+
session,
|
|
47
|
+
params: this.getParamsFromUrl(),
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
const session = this.getBotSessionContextFromUrl();
|
|
52
|
+
this.hubtypeApiUrl = session._hubtype_api || DEFAULT_HUBTYPE_API_URL;
|
|
53
|
+
this.setState({
|
|
54
|
+
session,
|
|
55
|
+
params: this.getParamsFromUrl(),
|
|
56
|
+
});
|
|
57
|
+
}
|
|
40
58
|
}
|
|
41
59
|
catch (error) {
|
|
42
|
-
console.error('
|
|
60
|
+
console.error('Failed to initialize app:', error);
|
|
61
|
+
const session = this.getBotSessionContextFromUrl();
|
|
62
|
+
this.hubtypeApiUrl = session._hubtype_api || DEFAULT_HUBTYPE_API_URL;
|
|
63
|
+
this.setState({
|
|
64
|
+
session,
|
|
65
|
+
params: this.getParamsFromUrl(),
|
|
66
|
+
});
|
|
43
67
|
}
|
|
44
68
|
});
|
|
45
69
|
}
|
|
46
|
-
|
|
70
|
+
getBotSessionContextFromExternalApi(hubtypeApiUrl, botId, userId) {
|
|
47
71
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
48
|
-
const url = `${
|
|
72
|
+
const url = `${hubtypeApiUrl}/external/v2/conversational_apps/${botId}/users/${userId}/context/`;
|
|
49
73
|
const response = yield axios_1.default.get(url);
|
|
50
74
|
return response.data;
|
|
51
75
|
});
|
|
52
76
|
}
|
|
77
|
+
getBotSessionContextFromUrl() {
|
|
78
|
+
const urlContext = this.url.searchParams.get(WebviewUrlParams.Context);
|
|
79
|
+
try {
|
|
80
|
+
return JSON.parse(urlContext || '{}');
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
console.error('Failed to parse session context from URL:', error);
|
|
84
|
+
return {};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
53
87
|
getParamsFromUrl() {
|
|
54
88
|
const keysToExclude = [
|
|
55
89
|
WebviewUrlParams.Context,
|
|
@@ -57,17 +91,62 @@ class App extends react_1.default.Component {
|
|
|
57
91
|
WebviewUrlParams.UserId,
|
|
58
92
|
WebviewUrlParams.HubtypeApiUrl,
|
|
59
93
|
];
|
|
60
|
-
|
|
61
|
-
.filter(([key
|
|
62
|
-
.reduce((
|
|
63
|
-
|
|
64
|
-
return
|
|
94
|
+
return Array.from(this.url.searchParams.entries())
|
|
95
|
+
.filter(([key]) => !keysToExclude.includes(key))
|
|
96
|
+
.reduce((params, [key, value]) => {
|
|
97
|
+
params[key] = value;
|
|
98
|
+
return params;
|
|
65
99
|
}, {});
|
|
66
|
-
|
|
100
|
+
}
|
|
101
|
+
closeWebviewForProvider(provider, session, payload) {
|
|
102
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
103
|
+
const { user } = session;
|
|
104
|
+
switch (provider) {
|
|
105
|
+
case core_1.PROVIDER.WHATSAPP:
|
|
106
|
+
location.href = `https://wa.me/${user.unformatted_phone_number}`;
|
|
107
|
+
break;
|
|
108
|
+
case core_1.PROVIDER.TELEGRAM:
|
|
109
|
+
location.href = `https://t.me/${user.imp_id}`;
|
|
110
|
+
break;
|
|
111
|
+
case core_1.PROVIDER.APPLE:
|
|
112
|
+
location.href = `https://bcrw.apple.com/urn:biz:${user.imp_id}`;
|
|
113
|
+
break;
|
|
114
|
+
case core_1.PROVIDER.TWITTER:
|
|
115
|
+
location.href = `https://twitter.com/messages/compose?recipient_id=${user.imp_id}`;
|
|
116
|
+
break;
|
|
117
|
+
case core_1.PROVIDER.INSTAGRAM:
|
|
118
|
+
window.close();
|
|
119
|
+
break;
|
|
120
|
+
case core_1.PROVIDER.FACEBOOK:
|
|
121
|
+
try {
|
|
122
|
+
window.MessengerExtensions.requestCloseBrowser(() => { }, // success callback
|
|
123
|
+
() => window.close() // error callback
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
window.close();
|
|
128
|
+
}
|
|
129
|
+
break;
|
|
130
|
+
case core_1.PROVIDER.WEBCHAT:
|
|
131
|
+
try {
|
|
132
|
+
yield parent.postMessage('botonicCloseWebview', '*');
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
console.error('Failed to send close message to parent:', error);
|
|
136
|
+
}
|
|
137
|
+
break;
|
|
138
|
+
default:
|
|
139
|
+
console.warn(`Unknown provider: ${provider}`);
|
|
140
|
+
}
|
|
141
|
+
});
|
|
67
142
|
}
|
|
68
143
|
close(options) {
|
|
69
144
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
70
|
-
|
|
145
|
+
if (!this.state.session) {
|
|
146
|
+
console.error('No session available for closing webview');
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
let payload = (options === null || options === void 0 ? void 0 : options.payload) || null;
|
|
71
150
|
if (options === null || options === void 0 ? void 0 : options.path) {
|
|
72
151
|
payload = `__PATH_PAYLOAD__${options.path}`;
|
|
73
152
|
}
|
|
@@ -75,52 +154,19 @@ class App extends react_1.default.Component {
|
|
|
75
154
|
if (options === null || options === void 0 ? void 0 : options.params) {
|
|
76
155
|
payload = `${payload}?${(0, core_1.params2queryString)(options.params)}`;
|
|
77
156
|
}
|
|
78
|
-
const session = this.state.session;
|
|
79
157
|
try {
|
|
80
|
-
const url = `${this.hubtypeApiUrl}/v1/bots/${this.
|
|
81
|
-
|
|
82
|
-
|
|
158
|
+
const url = `${this.hubtypeApiUrl}/v1/bots/${this.state.session.bot.id}/send_postback/`;
|
|
159
|
+
const data = {
|
|
160
|
+
payload,
|
|
161
|
+
chat_id: this.state.session.user.id,
|
|
162
|
+
};
|
|
83
163
|
yield axios_1.default.post(url, data);
|
|
84
164
|
}
|
|
85
|
-
catch (
|
|
86
|
-
console.
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
const provider = this.state.session.user.provider;
|
|
90
|
-
const impId = this.state.session.user.imp_id;
|
|
91
|
-
if (provider === core_1.PROVIDER.WHATSAPP) {
|
|
92
|
-
const phone_number = this.state.session.user.unformatted_phone_number;
|
|
93
|
-
location.href = 'https://wa.me/' + phone_number;
|
|
94
|
-
}
|
|
95
|
-
if (provider === core_1.PROVIDER.TELEGRAM) {
|
|
96
|
-
location.href = 'https://t.me/' + impId;
|
|
97
|
-
}
|
|
98
|
-
if (provider === core_1.PROVIDER.APPLE) {
|
|
99
|
-
location.href = 'https://bcrw.apple.com/urn:biz:' + impId;
|
|
100
|
-
}
|
|
101
|
-
if (provider === core_1.PROVIDER.TWITTER) {
|
|
102
|
-
location.href =
|
|
103
|
-
'https://twitter.com/messages/compose?recipient_id=' + impId;
|
|
104
|
-
}
|
|
105
|
-
if (provider === core_1.PROVIDER.INSTAGRAM) {
|
|
106
|
-
window.close();
|
|
107
|
-
}
|
|
108
|
-
if (provider === core_1.PROVIDER.FACEBOOK) {
|
|
109
|
-
try {
|
|
110
|
-
window.MessengerExtensions.requestCloseBrowser(function success() { }, function error(err) {
|
|
111
|
-
window.close();
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
catch (e) {
|
|
115
|
-
window.close();
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
if (provider === core_1.PROVIDER.WEBCHAT) {
|
|
119
|
-
try {
|
|
120
|
-
yield parent.postMessage('botonicCloseWebview', '*');
|
|
165
|
+
catch (error) {
|
|
166
|
+
console.error('Failed to send postback:', error);
|
|
121
167
|
}
|
|
122
|
-
catch (e) { }
|
|
123
168
|
}
|
|
169
|
+
yield this.closeWebviewForProvider(this.state.session.user.provider, this.state.session, payload);
|
|
124
170
|
});
|
|
125
171
|
}
|
|
126
172
|
render() {
|
|
@@ -145,8 +191,7 @@ class WebviewApp {
|
|
|
145
191
|
}
|
|
146
192
|
render(dest) {
|
|
147
193
|
const component = ((0, jsx_runtime_1.jsx)(react_router_dom_1.BrowserRouter, { children: (0, jsx_runtime_1.jsx)(App, { webviews: this.webviews, locales: this.locales }) }));
|
|
148
|
-
const
|
|
149
|
-
const reactRoot = (0, client_1.createRoot)(container);
|
|
194
|
+
const reactRoot = (0, client_1.createRoot)(dest);
|
|
150
195
|
reactRoot.render(component);
|
|
151
196
|
}
|
|
152
197
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webview-app.js","sourceRoot":"","sources":["../../src/webview-app.tsx"],"names":[],"mappings":";;;;;AAAA,cAAc;AACd,wCAAqE;AACrE,0DAAyB;AACzB,0DAAyB;AACzB,6CAA6C;AAC7C,uDAAuD;AAEvD,yCAImB;AAEnB,IAAK,gBAKJ;AALD,WAAK,gBAAgB;IACnB,uCAAmB,CAAA;IACnB,oCAAgB,CAAA;IAChB,sCAAkB,CAAA;IAClB,qDAAiC,CAAA;AACnC,CAAC,EALI,gBAAgB,KAAhB,gBAAgB,QAKpB;AAED,MAAM,GAAI,SAAQ,eAAK,CAAC,SAAS;
|
|
1
|
+
{"version":3,"file":"webview-app.js","sourceRoot":"","sources":["../../src/webview-app.tsx"],"names":[],"mappings":"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"}
|
package/lib/esm/webview-app.js
CHANGED
|
@@ -14,39 +14,73 @@ var WebviewUrlParams;
|
|
|
14
14
|
WebviewUrlParams["UserId"] = "user_id";
|
|
15
15
|
WebviewUrlParams["HubtypeApiUrl"] = "hubtype_api_url";
|
|
16
16
|
})(WebviewUrlParams || (WebviewUrlParams = {}));
|
|
17
|
+
const DEFAULT_HUBTYPE_API_URL = 'https://api.hubtype.com';
|
|
17
18
|
class App extends React.Component {
|
|
18
19
|
constructor(props) {
|
|
19
20
|
super(props);
|
|
21
|
+
this.hubtypeApiUrl = DEFAULT_HUBTYPE_API_URL;
|
|
20
22
|
this.url = new URL(window.location.href);
|
|
21
|
-
this.botId = this.url.searchParams.get(WebviewUrlParams.BotId);
|
|
22
|
-
this.userId = this.url.searchParams.get(WebviewUrlParams.UserId);
|
|
23
|
-
this.hubtypeApiUrl =
|
|
24
|
-
this.url.searchParams.get(WebviewUrlParams.HubtypeApiUrl) ||
|
|
25
|
-
'https://api.hubtype.com';
|
|
26
23
|
this.state = {
|
|
27
24
|
session: null,
|
|
28
25
|
params: {},
|
|
29
26
|
};
|
|
30
27
|
}
|
|
31
28
|
componentDidMount() {
|
|
29
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
30
|
+
yield this.initializeApp();
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
initializeApp() {
|
|
32
34
|
return __awaiter(this, void 0, void 0, function* () {
|
|
33
35
|
try {
|
|
34
|
-
const
|
|
35
|
-
const
|
|
36
|
-
this.
|
|
36
|
+
const botId = this.url.searchParams.get(WebviewUrlParams.BotId);
|
|
37
|
+
const chatId = this.url.searchParams.get(WebviewUrlParams.UserId);
|
|
38
|
+
const hubtypeApiUrl = this.url.searchParams.get(WebviewUrlParams.HubtypeApiUrl);
|
|
39
|
+
if (botId && chatId && hubtypeApiUrl) {
|
|
40
|
+
const session = yield this.getBotSessionContextFromExternalApi(hubtypeApiUrl, botId, chatId);
|
|
41
|
+
this.hubtypeApiUrl = hubtypeApiUrl;
|
|
42
|
+
this.setState({
|
|
43
|
+
session,
|
|
44
|
+
params: this.getParamsFromUrl(),
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
const session = this.getBotSessionContextFromUrl();
|
|
49
|
+
this.hubtypeApiUrl = session._hubtype_api || DEFAULT_HUBTYPE_API_URL;
|
|
50
|
+
this.setState({
|
|
51
|
+
session,
|
|
52
|
+
params: this.getParamsFromUrl(),
|
|
53
|
+
});
|
|
54
|
+
}
|
|
37
55
|
}
|
|
38
56
|
catch (error) {
|
|
39
|
-
console.error('
|
|
57
|
+
console.error('Failed to initialize app:', error);
|
|
58
|
+
const session = this.getBotSessionContextFromUrl();
|
|
59
|
+
this.hubtypeApiUrl = session._hubtype_api || DEFAULT_HUBTYPE_API_URL;
|
|
60
|
+
this.setState({
|
|
61
|
+
session,
|
|
62
|
+
params: this.getParamsFromUrl(),
|
|
63
|
+
});
|
|
40
64
|
}
|
|
41
65
|
});
|
|
42
66
|
}
|
|
43
|
-
|
|
67
|
+
getBotSessionContextFromExternalApi(hubtypeApiUrl, botId, userId) {
|
|
44
68
|
return __awaiter(this, void 0, void 0, function* () {
|
|
45
|
-
const url = `${
|
|
69
|
+
const url = `${hubtypeApiUrl}/external/v2/conversational_apps/${botId}/users/${userId}/context/`;
|
|
46
70
|
const response = yield axios.get(url);
|
|
47
71
|
return response.data;
|
|
48
72
|
});
|
|
49
73
|
}
|
|
74
|
+
getBotSessionContextFromUrl() {
|
|
75
|
+
const urlContext = this.url.searchParams.get(WebviewUrlParams.Context);
|
|
76
|
+
try {
|
|
77
|
+
return JSON.parse(urlContext || '{}');
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
console.error('Failed to parse session context from URL:', error);
|
|
81
|
+
return {};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
50
84
|
getParamsFromUrl() {
|
|
51
85
|
const keysToExclude = [
|
|
52
86
|
WebviewUrlParams.Context,
|
|
@@ -54,17 +88,62 @@ class App extends React.Component {
|
|
|
54
88
|
WebviewUrlParams.UserId,
|
|
55
89
|
WebviewUrlParams.HubtypeApiUrl,
|
|
56
90
|
];
|
|
57
|
-
|
|
58
|
-
.filter(([key
|
|
59
|
-
.reduce((
|
|
60
|
-
|
|
61
|
-
return
|
|
91
|
+
return Array.from(this.url.searchParams.entries())
|
|
92
|
+
.filter(([key]) => !keysToExclude.includes(key))
|
|
93
|
+
.reduce((params, [key, value]) => {
|
|
94
|
+
params[key] = value;
|
|
95
|
+
return params;
|
|
62
96
|
}, {});
|
|
63
|
-
|
|
97
|
+
}
|
|
98
|
+
closeWebviewForProvider(provider, session, payload) {
|
|
99
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
100
|
+
const { user } = session;
|
|
101
|
+
switch (provider) {
|
|
102
|
+
case PROVIDER.WHATSAPP:
|
|
103
|
+
location.href = `https://wa.me/${user.unformatted_phone_number}`;
|
|
104
|
+
break;
|
|
105
|
+
case PROVIDER.TELEGRAM:
|
|
106
|
+
location.href = `https://t.me/${user.imp_id}`;
|
|
107
|
+
break;
|
|
108
|
+
case PROVIDER.APPLE:
|
|
109
|
+
location.href = `https://bcrw.apple.com/urn:biz:${user.imp_id}`;
|
|
110
|
+
break;
|
|
111
|
+
case PROVIDER.TWITTER:
|
|
112
|
+
location.href = `https://twitter.com/messages/compose?recipient_id=${user.imp_id}`;
|
|
113
|
+
break;
|
|
114
|
+
case PROVIDER.INSTAGRAM:
|
|
115
|
+
window.close();
|
|
116
|
+
break;
|
|
117
|
+
case PROVIDER.FACEBOOK:
|
|
118
|
+
try {
|
|
119
|
+
window.MessengerExtensions.requestCloseBrowser(() => { }, // success callback
|
|
120
|
+
() => window.close() // error callback
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
window.close();
|
|
125
|
+
}
|
|
126
|
+
break;
|
|
127
|
+
case PROVIDER.WEBCHAT:
|
|
128
|
+
try {
|
|
129
|
+
yield parent.postMessage('botonicCloseWebview', '*');
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
console.error('Failed to send close message to parent:', error);
|
|
133
|
+
}
|
|
134
|
+
break;
|
|
135
|
+
default:
|
|
136
|
+
console.warn(`Unknown provider: ${provider}`);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
64
139
|
}
|
|
65
140
|
close(options) {
|
|
66
141
|
return __awaiter(this, void 0, void 0, function* () {
|
|
67
|
-
|
|
142
|
+
if (!this.state.session) {
|
|
143
|
+
console.error('No session available for closing webview');
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
let payload = (options === null || options === void 0 ? void 0 : options.payload) || null;
|
|
68
147
|
if (options === null || options === void 0 ? void 0 : options.path) {
|
|
69
148
|
payload = `__PATH_PAYLOAD__${options.path}`;
|
|
70
149
|
}
|
|
@@ -72,52 +151,19 @@ class App extends React.Component {
|
|
|
72
151
|
if (options === null || options === void 0 ? void 0 : options.params) {
|
|
73
152
|
payload = `${payload}?${params2queryString(options.params)}`;
|
|
74
153
|
}
|
|
75
|
-
const session = this.state.session;
|
|
76
154
|
try {
|
|
77
|
-
const url = `${this.hubtypeApiUrl}/v1/bots/${this.
|
|
78
|
-
|
|
79
|
-
|
|
155
|
+
const url = `${this.hubtypeApiUrl}/v1/bots/${this.state.session.bot.id}/send_postback/`;
|
|
156
|
+
const data = {
|
|
157
|
+
payload,
|
|
158
|
+
chat_id: this.state.session.user.id,
|
|
159
|
+
};
|
|
80
160
|
yield axios.post(url, data);
|
|
81
161
|
}
|
|
82
|
-
catch (
|
|
83
|
-
console.
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
const provider = this.state.session.user.provider;
|
|
87
|
-
const impId = this.state.session.user.imp_id;
|
|
88
|
-
if (provider === PROVIDER.WHATSAPP) {
|
|
89
|
-
const phone_number = this.state.session.user.unformatted_phone_number;
|
|
90
|
-
location.href = 'https://wa.me/' + phone_number;
|
|
91
|
-
}
|
|
92
|
-
if (provider === PROVIDER.TELEGRAM) {
|
|
93
|
-
location.href = 'https://t.me/' + impId;
|
|
94
|
-
}
|
|
95
|
-
if (provider === PROVIDER.APPLE) {
|
|
96
|
-
location.href = 'https://bcrw.apple.com/urn:biz:' + impId;
|
|
97
|
-
}
|
|
98
|
-
if (provider === PROVIDER.TWITTER) {
|
|
99
|
-
location.href =
|
|
100
|
-
'https://twitter.com/messages/compose?recipient_id=' + impId;
|
|
101
|
-
}
|
|
102
|
-
if (provider === PROVIDER.INSTAGRAM) {
|
|
103
|
-
window.close();
|
|
104
|
-
}
|
|
105
|
-
if (provider === PROVIDER.FACEBOOK) {
|
|
106
|
-
try {
|
|
107
|
-
window.MessengerExtensions.requestCloseBrowser(function success() { }, function error(err) {
|
|
108
|
-
window.close();
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
catch (e) {
|
|
112
|
-
window.close();
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
if (provider === PROVIDER.WEBCHAT) {
|
|
116
|
-
try {
|
|
117
|
-
yield parent.postMessage('botonicCloseWebview', '*');
|
|
162
|
+
catch (error) {
|
|
163
|
+
console.error('Failed to send postback:', error);
|
|
118
164
|
}
|
|
119
|
-
catch (e) { }
|
|
120
165
|
}
|
|
166
|
+
yield this.closeWebviewForProvider(this.state.session.user.provider, this.state.session, payload);
|
|
121
167
|
});
|
|
122
168
|
}
|
|
123
169
|
render() {
|
|
@@ -142,8 +188,7 @@ export class WebviewApp {
|
|
|
142
188
|
}
|
|
143
189
|
render(dest) {
|
|
144
190
|
const component = (_jsx(BrowserRouter, { children: _jsx(App, { webviews: this.webviews, locales: this.locales }) }));
|
|
145
|
-
const
|
|
146
|
-
const reactRoot = createRoot(container);
|
|
191
|
+
const reactRoot = createRoot(dest);
|
|
147
192
|
reactRoot.render(component);
|
|
148
193
|
}
|
|
149
194
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webview-app.js","sourceRoot":"","sources":["../../src/webview-app.tsx"],"names":[],"mappings":";;AAAA,cAAc;AACd,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAW,MAAM,eAAe,CAAA;AACrE,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAEvD,OAAO,EAEL,qBAAqB,GAEtB,MAAM,YAAY,CAAA;AAEnB,IAAK,gBAKJ;AALD,WAAK,gBAAgB;IACnB,uCAAmB,CAAA;IACnB,oCAAgB,CAAA;IAChB,sCAAkB,CAAA;IAClB,qDAAiC,CAAA;AACnC,CAAC,EALI,gBAAgB,KAAhB,gBAAgB,QAKpB;AAED,MAAM,GAAI,SAAQ,KAAK,CAAC,SAAS;
|
|
1
|
+
{"version":3,"file":"webview-app.js","sourceRoot":"","sources":["../../src/webview-app.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/webview-app.tsx
CHANGED
|
@@ -18,21 +18,15 @@ enum WebviewUrlParams {
|
|
|
18
18
|
HubtypeApiUrl = 'hubtype_api_url',
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
const DEFAULT_HUBTYPE_API_URL = 'https://api.hubtype.com'
|
|
22
|
+
|
|
21
23
|
class App extends React.Component {
|
|
22
24
|
private url: URL
|
|
23
|
-
private
|
|
24
|
-
private userId: string
|
|
25
|
-
private hubtypeApiUrl: string
|
|
26
|
-
private state: { session: Session; params: Record<string, string> }
|
|
25
|
+
private hubtypeApiUrl: string = DEFAULT_HUBTYPE_API_URL
|
|
27
26
|
|
|
28
27
|
constructor(props) {
|
|
29
28
|
super(props)
|
|
30
29
|
this.url = new URL(window.location.href)
|
|
31
|
-
this.botId = this.url.searchParams.get(WebviewUrlParams.BotId)
|
|
32
|
-
this.userId = this.url.searchParams.get(WebviewUrlParams.UserId)
|
|
33
|
-
this.hubtypeApiUrl =
|
|
34
|
-
this.url.searchParams.get(WebviewUrlParams.HubtypeApiUrl) ||
|
|
35
|
-
'https://api.hubtype.com'
|
|
36
30
|
this.state = {
|
|
37
31
|
session: null,
|
|
38
32
|
params: {},
|
|
@@ -40,39 +34,134 @@ class App extends React.Component {
|
|
|
40
34
|
}
|
|
41
35
|
|
|
42
36
|
async componentDidMount() {
|
|
37
|
+
await this.initializeApp()
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
private async initializeApp() {
|
|
43
41
|
try {
|
|
44
|
-
const
|
|
45
|
-
const
|
|
46
|
-
this.
|
|
42
|
+
const botId = this.url.searchParams.get(WebviewUrlParams.BotId)
|
|
43
|
+
const chatId = this.url.searchParams.get(WebviewUrlParams.UserId)
|
|
44
|
+
const hubtypeApiUrl = this.url.searchParams.get(
|
|
45
|
+
WebviewUrlParams.HubtypeApiUrl
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
if (botId && chatId && hubtypeApiUrl) {
|
|
49
|
+
const session = await this.getBotSessionContextFromExternalApi(
|
|
50
|
+
hubtypeApiUrl,
|
|
51
|
+
botId,
|
|
52
|
+
chatId
|
|
53
|
+
)
|
|
54
|
+
this.hubtypeApiUrl = hubtypeApiUrl
|
|
55
|
+
this.setState({
|
|
56
|
+
session,
|
|
57
|
+
params: this.getParamsFromUrl(),
|
|
58
|
+
})
|
|
59
|
+
} else {
|
|
60
|
+
const session = this.getBotSessionContextFromUrl()
|
|
61
|
+
this.hubtypeApiUrl = session._hubtype_api || DEFAULT_HUBTYPE_API_URL
|
|
62
|
+
this.setState({
|
|
63
|
+
session,
|
|
64
|
+
params: this.getParamsFromUrl(),
|
|
65
|
+
})
|
|
66
|
+
}
|
|
47
67
|
} catch (error) {
|
|
48
|
-
console.error('
|
|
68
|
+
console.error('Failed to initialize app:', error)
|
|
69
|
+
const session = this.getBotSessionContextFromUrl()
|
|
70
|
+
this.hubtypeApiUrl = session._hubtype_api || DEFAULT_HUBTYPE_API_URL
|
|
71
|
+
this.setState({
|
|
72
|
+
session,
|
|
73
|
+
params: this.getParamsFromUrl(),
|
|
74
|
+
})
|
|
49
75
|
}
|
|
50
76
|
}
|
|
51
77
|
|
|
52
|
-
async
|
|
53
|
-
|
|
78
|
+
private async getBotSessionContextFromExternalApi(
|
|
79
|
+
hubtypeApiUrl: string,
|
|
80
|
+
botId: string,
|
|
81
|
+
userId: string
|
|
82
|
+
) {
|
|
83
|
+
const url = `${hubtypeApiUrl}/external/v2/conversational_apps/${botId}/users/${userId}/context/`
|
|
54
84
|
const response = await axios.get(url)
|
|
55
85
|
return response.data
|
|
56
86
|
}
|
|
57
87
|
|
|
58
|
-
|
|
88
|
+
private getBotSessionContextFromUrl() {
|
|
89
|
+
const urlContext = this.url.searchParams.get(WebviewUrlParams.Context)
|
|
90
|
+
try {
|
|
91
|
+
return JSON.parse(urlContext || '{}')
|
|
92
|
+
} catch (error) {
|
|
93
|
+
console.error('Failed to parse session context from URL:', error)
|
|
94
|
+
return {}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
private getParamsFromUrl() {
|
|
59
99
|
const keysToExclude = [
|
|
60
100
|
WebviewUrlParams.Context,
|
|
61
101
|
WebviewUrlParams.BotId,
|
|
62
102
|
WebviewUrlParams.UserId,
|
|
63
103
|
WebviewUrlParams.HubtypeApiUrl,
|
|
64
104
|
]
|
|
65
|
-
|
|
66
|
-
.filter(([key
|
|
67
|
-
.reduce((
|
|
68
|
-
|
|
69
|
-
return
|
|
105
|
+
return Array.from(this.url.searchParams.entries())
|
|
106
|
+
.filter(([key]) => !keysToExclude.includes(key))
|
|
107
|
+
.reduce((params, [key, value]) => {
|
|
108
|
+
params[key] = value
|
|
109
|
+
return params
|
|
70
110
|
}, {})
|
|
71
|
-
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
private async closeWebviewForProvider(
|
|
114
|
+
provider: string,
|
|
115
|
+
session: Session,
|
|
116
|
+
payload?: string
|
|
117
|
+
) {
|
|
118
|
+
const { user } = session
|
|
119
|
+
|
|
120
|
+
switch (provider) {
|
|
121
|
+
case PROVIDER.WHATSAPP:
|
|
122
|
+
location.href = `https://wa.me/${user.unformatted_phone_number}`
|
|
123
|
+
break
|
|
124
|
+
case PROVIDER.TELEGRAM:
|
|
125
|
+
location.href = `https://t.me/${user.imp_id}`
|
|
126
|
+
break
|
|
127
|
+
case PROVIDER.APPLE:
|
|
128
|
+
location.href = `https://bcrw.apple.com/urn:biz:${user.imp_id}`
|
|
129
|
+
break
|
|
130
|
+
case PROVIDER.TWITTER:
|
|
131
|
+
location.href = `https://twitter.com/messages/compose?recipient_id=${user.imp_id}`
|
|
132
|
+
break
|
|
133
|
+
case PROVIDER.INSTAGRAM:
|
|
134
|
+
window.close()
|
|
135
|
+
break
|
|
136
|
+
case PROVIDER.FACEBOOK:
|
|
137
|
+
try {
|
|
138
|
+
window.MessengerExtensions.requestCloseBrowser(
|
|
139
|
+
() => {}, // success callback
|
|
140
|
+
() => window.close() // error callback
|
|
141
|
+
)
|
|
142
|
+
} catch (error) {
|
|
143
|
+
window.close()
|
|
144
|
+
}
|
|
145
|
+
break
|
|
146
|
+
case PROVIDER.WEBCHAT:
|
|
147
|
+
try {
|
|
148
|
+
await parent.postMessage('botonicCloseWebview', '*')
|
|
149
|
+
} catch (error) {
|
|
150
|
+
console.error('Failed to send close message to parent:', error)
|
|
151
|
+
}
|
|
152
|
+
break
|
|
153
|
+
default:
|
|
154
|
+
console.warn(`Unknown provider: ${provider}`)
|
|
155
|
+
}
|
|
72
156
|
}
|
|
73
157
|
|
|
74
158
|
async close(options?: CloseWebviewOptions) {
|
|
75
|
-
|
|
159
|
+
if (!this.state.session) {
|
|
160
|
+
console.error('No session available for closing webview')
|
|
161
|
+
return
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
let payload = options?.payload || null
|
|
76
165
|
|
|
77
166
|
if (options?.path) {
|
|
78
167
|
payload = `__PATH_PAYLOAD__${options.path}`
|
|
@@ -83,53 +172,23 @@ class App extends React.Component {
|
|
|
83
172
|
payload = `${payload}?${params2queryString(options.params)}`
|
|
84
173
|
}
|
|
85
174
|
|
|
86
|
-
const session = this.state.session
|
|
87
175
|
try {
|
|
88
|
-
const url = `${this.hubtypeApiUrl}/v1/bots/${this.
|
|
89
|
-
|
|
90
|
-
|
|
176
|
+
const url = `${this.hubtypeApiUrl}/v1/bots/${this.state.session.bot.id}/send_postback/`
|
|
177
|
+
const data = {
|
|
178
|
+
payload,
|
|
179
|
+
chat_id: this.state.session.user.id,
|
|
180
|
+
}
|
|
91
181
|
await axios.post(url, data)
|
|
92
|
-
} catch (
|
|
93
|
-
console.
|
|
182
|
+
} catch (error) {
|
|
183
|
+
console.error('Failed to send postback:', error)
|
|
94
184
|
}
|
|
95
185
|
}
|
|
96
186
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
}
|
|
103
|
-
if (provider === PROVIDER.TELEGRAM) {
|
|
104
|
-
location.href = 'https://t.me/' + impId
|
|
105
|
-
}
|
|
106
|
-
if (provider === PROVIDER.APPLE) {
|
|
107
|
-
location.href = 'https://bcrw.apple.com/urn:biz:' + impId
|
|
108
|
-
}
|
|
109
|
-
if (provider === PROVIDER.TWITTER) {
|
|
110
|
-
location.href =
|
|
111
|
-
'https://twitter.com/messages/compose?recipient_id=' + impId
|
|
112
|
-
}
|
|
113
|
-
if (provider === PROVIDER.INSTAGRAM) {
|
|
114
|
-
window.close()
|
|
115
|
-
}
|
|
116
|
-
if (provider === PROVIDER.FACEBOOK) {
|
|
117
|
-
try {
|
|
118
|
-
window.MessengerExtensions.requestCloseBrowser(
|
|
119
|
-
function success() {},
|
|
120
|
-
function error(err) {
|
|
121
|
-
window.close()
|
|
122
|
-
}
|
|
123
|
-
)
|
|
124
|
-
} catch (e) {
|
|
125
|
-
window.close()
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
if (provider === PROVIDER.WEBCHAT) {
|
|
129
|
-
try {
|
|
130
|
-
await parent.postMessage('botonicCloseWebview', '*')
|
|
131
|
-
} catch (e) {}
|
|
132
|
-
}
|
|
187
|
+
await this.closeWebviewForProvider(
|
|
188
|
+
this.state.session.user.provider,
|
|
189
|
+
this.state.session,
|
|
190
|
+
payload
|
|
191
|
+
)
|
|
133
192
|
}
|
|
134
193
|
|
|
135
194
|
render() {
|
|
@@ -168,8 +227,7 @@ export class WebviewApp {
|
|
|
168
227
|
<App webviews={this.webviews} locales={this.locales} />
|
|
169
228
|
</BrowserRouter>
|
|
170
229
|
)
|
|
171
|
-
const
|
|
172
|
-
const reactRoot = createRoot(container)
|
|
230
|
+
const reactRoot = createRoot(dest)
|
|
173
231
|
reactRoot.render(component)
|
|
174
232
|
}
|
|
175
233
|
}
|