@subiz/widget-v4 4.1.214 → 4.1.215

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 (30) hide show
  1. package/api.md +20 -8
  2. package/compiled_src/lib.js +2 -15
  3. package/compiled_src/store/api.js +0 -1
  4. package/compiled_src/store/store.js +65 -1
  5. package/dist/.HASH +1 -1
  6. package/dist/{1a12a372880.app.js → 1a12a5ed6a9.app.js} +1 -1
  7. package/dist/{1a12a372880.chat.html → 1a12a5ed6a9.chat.html} +1 -1
  8. package/dist/{1a12a372880.chat.js → 1a12a5ed6a9.chat.js} +1 -1
  9. package/dist/{1a12a372880.form.html → 1a12a5ed6a9.form.html} +1 -1
  10. package/dist/1a12a5ed6a9.form.js +1 -0
  11. package/dist/{1a12a372880.index.html → 1a12a5ed6a9.index.html} +1 -1
  12. package/dist/{1a12a372880.library.html → 1a12a5ed6a9.library.html} +1 -1
  13. package/dist/{1a12a372880.library.js → 1a12a5ed6a9.library.js} +1 -1
  14. package/dist/{1a12a372880.preview.html → 1a12a5ed6a9.preview.html} +1 -1
  15. package/dist/{1a12a372880.preview.js → 1a12a5ed6a9.preview.js} +1 -1
  16. package/dist/{1a12a372880.webview.js → 1a12a5ed6a9.webview.js} +1 -1
  17. package/dist/screenshoot.js +66 -16
  18. package/package.json +1 -1
  19. package/src/lib.js +2 -18
  20. package/src/store/api.js +0 -3
  21. package/src/store/store.js +51 -0
  22. package/dist/1a12a372880.form.js +0 -1
  23. /package/dist/{1a12a372880.127.js → 1a12a5ed6a9.127.js} +0 -0
  24. /package/dist/{1a12a372880.132.js → 1a12a5ed6a9.132.js} +0 -0
  25. /package/dist/{1a12a372880.185.js → 1a12a5ed6a9.185.js} +0 -0
  26. /package/dist/{1a12a372880.27.js → 1a12a5ed6a9.27.js} +0 -0
  27. /package/dist/{1a12a372880.278.js → 1a12a5ed6a9.278.js} +0 -0
  28. /package/dist/{1a12a372880.339.js → 1a12a5ed6a9.339.js} +0 -0
  29. /package/dist/{1a12a372880.459.js → 1a12a5ed6a9.459.js} +0 -0
  30. /package/dist/{1a12a372880.490.js → 1a12a5ed6a9.490.js} +0 -0
@@ -4588,7 +4588,6 @@ let trackResponseFn = (param, done) => {
4588
4588
  _defineProperty(this, "sendEvent", data => this.apireq.addQuery('shorten', true).addQuery('x-referer', util/* default */.A.get(location, 'origin', '')).post(`/accounts/${this.accid}/users/${this.uid}/events`, data));
4589
4589
  _defineProperty(this, "websiteFormRequest", () => this.apireq.setBaseUrl(this.ApiURL.replace(/\/4\.[01]\/?$/, '/4.1')));
4590
4590
  _defineProperty(this, "submitWebsiteForm", (formid, payload) => this.websiteFormRequest().post(`/accounts/${this.accid}/external-forms/${encodeURIComponent(formid)}/submissions`, payload));
4591
- _defineProperty(this, "getWebsiteFormStatus", formid => this.websiteFormRequest().get(`/accounts/${this.accid}/external-forms/${encodeURIComponent(formid)}/status`));
4592
4591
  _defineProperty(this, "submitForm", (form_id, page_url, device, data, user) => this.apireq.addQuery('x-referer', util/* default */.A.get(location, 'origin', '')).post(`/accounts/${this.accid}/users/${this.uid}/events`, {
4593
4592
  by: {
4594
4593
  id: this.uid,
@@ -6580,6 +6579,53 @@ class Store {
6580
6579
  this.reconnectGate.open();
6581
6580
  }
6582
6581
  }
6582
+ async submitWebsiteForm(formid, payload) {
6583
+ await this.readyGate.entry();
6584
+ const key = websiteFormStorageKey(this.api, formid);
6585
+ const kv = this.kv;
6586
+ const result = formResult(await this.api.submitWebsiteForm(formid, payload));
6587
+ try {
6588
+ kv.put(key, {
6589
+ conversation_id: result.conversation_id,
6590
+ expires_at: util/* default */.A.Date.now() + 7 * 24 * 60 * 60 * 1000
6591
+ });
6592
+ } catch (_) {}
6593
+ return result;
6594
+ }
6595
+ getFormStatus(formid) {
6596
+ const key = websiteFormStorageKey(this.api, formid);
6597
+ try {
6598
+ const receipt = this.kv.match(key);
6599
+ if (!receipt) return {
6600
+ submitted: false,
6601
+ status: 'not_found'
6602
+ };
6603
+ if (!Number.isFinite(receipt.expires_at) || typeof receipt.conversation_id !== 'string' || !receipt.conversation_id) {
6604
+ this.kv.del(key);
6605
+ return {
6606
+ submitted: false,
6607
+ status: 'not_found'
6608
+ };
6609
+ }
6610
+ if (receipt.expires_at <= util/* default */.A.Date.now()) {
6611
+ this.kv.del(key);
6612
+ return {
6613
+ submitted: false,
6614
+ status: 'expired'
6615
+ };
6616
+ }
6617
+ return {
6618
+ submitted: true,
6619
+ status: 'found',
6620
+ conversation_id: receipt.conversation_id
6621
+ };
6622
+ } catch (_) {
6623
+ return {
6624
+ submitted: false,
6625
+ status: 'storage_unavailable'
6626
+ };
6627
+ }
6628
+ }
6583
6629
  async submitForm(formid, data, user) {
6584
6630
  await this.readyGate.entry();
6585
6631
  if (user) await this.setUser(user);
@@ -6707,6 +6753,7 @@ class Store {
6707
6753
  async _onWs(ev) {
6708
6754
  if (this._die) return;
6709
6755
  if (!ev || !ev.type) return;
6756
+ if (util/* default */.A.get(ev, 'touchpoint.channel') === 'form' || util/* default */.A.get(ev, 'data.conversation.touchpoint.channel') === 'form') return;
6710
6757
  ev.created = util/* default */.A.getMs(ev.created);
6711
6758
  if (ev.type === 'user_info_updated') {
6712
6759
  return;
@@ -7462,6 +7509,22 @@ var xhrsend = function (method, url, body, cb) {
7462
7509
  request.send(body);
7463
7510
  };
7464
7511
  const dieErr = new Error('sdk unloaded');
7512
+ function websiteFormStorageKey(api, formid) {
7513
+ return 'sbz_form_submitted:' + util/* default */.A.stringify([api.accid, api.uid, formid]);
7514
+ }
7515
+ function formResult(response) {
7516
+ const body = response && response.body;
7517
+ const detail = response && response.error || body && body.error;
7518
+ const status = response && response.code;
7519
+ const valid = body && typeof body.conversation_id === 'string' && body.conversation_id && typeof body.submission_id === 'string' && body.submission_id;
7520
+ if (detail || !(status >= 200 && status < 300) || !valid) {
7521
+ const error = new Error('Subiz form request failed');
7522
+ error.code = detail && detail.code || 'form_request_failed';
7523
+ error.status = status;
7524
+ throw error;
7525
+ }
7526
+ return body;
7527
+ }
7465
7528
  // EXTERNAL MODULE: ./src/common.js
7466
7529
  var common = __webpack_require__(2840);
7467
7530
  // EXTERNAL MODULE: ./node_modules/preact/dist/preact.module.js
@@ -14186,12 +14249,12 @@ class lib_Widget {
14186
14249
  return this.store.sendConversion(formid, values, impressiontoken);
14187
14250
  }
14188
14251
  const payload = formRequest(formid, values, options);
14189
- return formResult(await this.store.api.submitWebsiteForm(formid, payload), 'submit');
14252
+ return this.store.submitWebsiteForm(formid, payload);
14190
14253
  }
14191
14254
  async getFormStatus(formid) {
14192
14255
  validateWebsiteFormId(formid);
14193
14256
  await this.store.readyGate.entry();
14194
- return formResult(await this.store.api.getWebsiteFormStatus(formid), 'status');
14257
+ return this.store.getFormStatus(formid);
14195
14258
  }
14196
14259
  startConvo(req) {
14197
14260
  req = util/* default */.A.cloneDeep(req) || {};
@@ -14332,19 +14395,6 @@ function formRequest(formid, fields, options = {}) {
14332
14395
  })
14333
14396
  };
14334
14397
  }
14335
- function formResult(response, operation) {
14336
- const body = response && response.body;
14337
- const detail = response && response.error || body && body.error;
14338
- const status = response && response.code;
14339
- const valid = operation === 'submit' ? body && typeof body.conversation_id === 'string' && body.conversation_id && typeof body.submission_id === 'string' && body.submission_id : body && typeof body.submitted === 'boolean' && typeof body.status === 'string';
14340
- if (detail || !(status >= 200 && status < 300) || !valid) {
14341
- const error = new Error('Subiz form request failed');
14342
- error.code = detail && detail.code || 'form_request_failed';
14343
- error.status = status;
14344
- throw error;
14345
- }
14346
- return body;
14347
- }
14348
14398
  ;// ./screenshoot.js
14349
14399
 
14350
14400
  let accid = 'acqsulrowbxiugvginhw';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@subiz/widget-v4",
3
- "version": "4.1.214",
3
+ "version": "4.1.215",
4
4
  "main": "./compiled_src/lib.js",
5
5
  "scripts": {
6
6
  "dev": "npx webpack serve --config webpack.dev.js",
package/src/lib.js CHANGED
@@ -235,13 +235,13 @@ class Widget {
235
235
  }
236
236
 
237
237
  const payload = formRequest(formid, values, options)
238
- return formResult(await this.store.api.submitWebsiteForm(formid, payload), 'submit')
238
+ return this.store.submitWebsiteForm(formid, payload)
239
239
  }
240
240
 
241
241
  async getFormStatus(formid) {
242
242
  validateWebsiteFormId(formid)
243
243
  await this.store.readyGate.entry()
244
- return formResult(await this.store.api.getWebsiteFormStatus(formid), 'status')
244
+ return this.store.getFormStatus(formid)
245
245
  }
246
246
 
247
247
  // req.bot_id != "" -> start conversation with bot id
@@ -418,19 +418,3 @@ function formRequest(formid, fields, options = {}) {
418
418
  }),
419
419
  }
420
420
  }
421
-
422
- function formResult(response, operation) {
423
- const body = response && response.body
424
- const detail = (response && response.error) || (body && body.error)
425
- const status = response && response.code
426
- const valid = operation === 'submit'
427
- ? body && typeof body.conversation_id === 'string' && body.conversation_id && typeof body.submission_id === 'string' && body.submission_id
428
- : body && typeof body.submitted === 'boolean' && typeof body.status === 'string'
429
- if (detail || !(status >= 200 && status < 300) || !valid) {
430
- const error = new Error('Subiz form request failed')
431
- error.code = (detail && detail.code) || 'form_request_failed'
432
- error.status = status
433
- throw error
434
- }
435
- return body
436
- }
package/src/store/api.js CHANGED
@@ -277,9 +277,6 @@ export default class {
277
277
  submitWebsiteForm = (formid, payload) => this.websiteFormRequest()
278
278
  .post(`/accounts/${this.accid}/external-forms/${encodeURIComponent(formid)}/submissions`, payload)
279
279
 
280
- getWebsiteFormStatus = (formid) => this.websiteFormRequest()
281
- .get(`/accounts/${this.accid}/external-forms/${encodeURIComponent(formid)}/status`)
282
-
283
280
  submitForm = (form_id, page_url, device, data, user) =>
284
281
  this.apireq
285
282
  .addQuery('x-referer', sb.get(location, 'origin', ''))
@@ -955,6 +955,36 @@ export default class Store {
955
955
  }
956
956
  }
957
957
 
958
+ async submitWebsiteForm(formid, payload) {
959
+ await this.readyGate.entry()
960
+ const key = websiteFormStorageKey(this.api, formid)
961
+ const kv = this.kv
962
+ const result = formResult(await this.api.submitWebsiteForm(formid, payload))
963
+ try {
964
+ kv.put(key, {conversation_id: result.conversation_id, expires_at: sb.Date.now() + 7 * 24 * 60 * 60 * 1000})
965
+ } catch (_) { /* Storage failure must not make callers retry a successful submission. */ }
966
+ return result
967
+ }
968
+
969
+ getFormStatus(formid) {
970
+ const key = websiteFormStorageKey(this.api, formid)
971
+ try {
972
+ const receipt = this.kv.match(key)
973
+ if (!receipt) return {submitted: false, status: 'not_found'}
974
+ if (!Number.isFinite(receipt.expires_at) || typeof receipt.conversation_id !== 'string' || !receipt.conversation_id) {
975
+ this.kv.del(key)
976
+ return {submitted: false, status: 'not_found'}
977
+ }
978
+ if (receipt.expires_at <= sb.Date.now()) {
979
+ this.kv.del(key)
980
+ return {submitted: false, status: 'expired'}
981
+ }
982
+ return {submitted: true, status: 'found', conversation_id: receipt.conversation_id}
983
+ } catch (_) {
984
+ return {submitted: false, status: 'storage_unavailable'}
985
+ }
986
+ }
987
+
958
988
  async submitForm(formid, data, user) {
959
989
  await this.readyGate.entry()
960
990
  if (user) await this.setUser(user)
@@ -1117,6 +1147,9 @@ export default class Store {
1117
1147
  async _onWs(ev) {
1118
1148
  if (this._die) return
1119
1149
  if (!ev || !ev.type) return
1150
+ // Website form conversations are handled in the agent inbox, not the chat widget.
1151
+ // Ignore their realtime events before an unknown conversation triggers a GET.
1152
+ if (sb.get(ev, 'touchpoint.channel') === 'form' || sb.get(ev, 'data.conversation.touchpoint.channel') === 'form') return
1120
1153
  ev.created = sb.getMs(ev.created)
1121
1154
  if (ev.type === 'user_info_updated') {
1122
1155
  return
@@ -1916,3 +1949,21 @@ var xhrsend = function (method, url, body, cb) {
1916
1949
  }
1917
1950
 
1918
1951
  const dieErr = new Error('sdk unloaded')
1952
+
1953
+ function websiteFormStorageKey(api, formid) {
1954
+ return 'sbz_form_submitted:' + sb.stringify([api.accid, api.uid, formid])
1955
+ }
1956
+
1957
+ function formResult(response) {
1958
+ const body = response && response.body
1959
+ const detail = (response && response.error) || (body && body.error)
1960
+ const status = response && response.code
1961
+ const valid = body && typeof body.conversation_id === 'string' && body.conversation_id && typeof body.submission_id === 'string' && body.submission_id
1962
+ if (detail || !(status >= 200 && status < 300) || !valid) {
1963
+ const error = new Error('Subiz form request failed')
1964
+ error.code = (detail && detail.code) || 'form_request_failed'
1965
+ error.status = status
1966
+ throw error
1967
+ }
1968
+ return body
1969
+ }