@smartico/public-api 0.0.433 → 0.0.435
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/dist/Inbox/InboxMessage.d.ts +1 -1
- package/dist/MiniGames/SAWTemplateUI.d.ts +26 -0
- package/dist/SmarticoGlobal.d.ts +18 -0
- package/dist/WSAPI/WSAPIInbox.d.ts +16 -0
- package/dist/WSAPI/WSAPITypes.d.ts +6 -0
- package/dist/index.js +57 -49
- package/dist/index.js.map +1 -1
- package/dist/index.modern.mjs +48 -44
- package/dist/index.modern.mjs.map +1 -1
- package/docs/ui/inbox/UIGuide_getInboxMessageBody.md +24 -2
- package/package.json +1 -1
- package/src/Inbox/InboxMessage.ts +3 -1
- package/src/MiniGames/SAWTemplateUI.ts +29 -0
- package/src/Missions/MissionsUtils.ts +37 -47
- package/src/Missions/UserAchievement.ts +3 -3
- package/src/SmarticoGlobal.ts +18 -0
- package/src/WSAPI/WSAPIInbox.ts +16 -0
- package/src/WSAPI/WSAPITypes.ts +6 -0
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
## Overview
|
|
4
4
|
- Returns the rich body (title, preview, icon, action, html_body,
|
|
5
|
-
buttons, custom_data)
|
|
6
|
-
`
|
|
5
|
+
buttons, custom_data) and the preview-popup settings
|
|
6
|
+
(`show_preview`, `show_duration_sec`) for one message identified
|
|
7
|
+
by its `message_guid`.
|
|
7
8
|
- Fetched from a CDN, NOT over the WebSocket — latency depends on
|
|
8
9
|
CDN proximity. No SDK-level cache (browser HTTP cache may apply
|
|
9
10
|
via CDN Cache-Control headers).
|
|
@@ -42,6 +43,27 @@ payload has `html_body` or `buttons` but the action isn't
|
|
|
42
43
|
consumer. Don't try to render `html_body` for non-`'dp:inbox'`
|
|
43
44
|
messages — it will be `undefined`.
|
|
44
45
|
|
|
46
|
+
## Preview popup vs silent delivery
|
|
47
|
+
|
|
48
|
+
Every message is stored in the inbox list. The preview settings
|
|
49
|
+
decide whether a newly arrived message also pops up briefly (the
|
|
50
|
+
"toast" the default Smartico UI shows while the user is online).
|
|
51
|
+
|
|
52
|
+
| Field | Value | Behaviour |
|
|
53
|
+
|---|---|---|
|
|
54
|
+
| `show_preview` | `true` or missing | Show a preview popup and store the message in the list |
|
|
55
|
+
| `show_preview` | `false` | Store the message silently, with no popup |
|
|
56
|
+
| `show_duration_sec` | number | Hide the popup after this many seconds |
|
|
57
|
+
| `show_duration_sec` | `null` or missing | Hide the popup after 7 seconds (the default Smartico UI's default) |
|
|
58
|
+
|
|
59
|
+
Values are returned exactly as the operator configured them, so
|
|
60
|
+
apply the defaults above yourself (e.g. `body.show_preview !== false`,
|
|
61
|
+
`body.show_duration_sec ?? 7`).
|
|
62
|
+
|
|
63
|
+
Only show the popup for messages that arrive while the user is
|
|
64
|
+
online. Messages loaded from history via {@link getInboxMessages}
|
|
65
|
+
should go straight into the list.
|
|
66
|
+
|
|
45
67
|
## Sandboxed iframe (for `html_body`)
|
|
46
68
|
|
|
47
69
|
`html_body` is operator-supplied HTML. **Render in a sandboxed
|
package/package.json
CHANGED
|
@@ -23,7 +23,7 @@ export interface InboxMessageBody {
|
|
|
23
23
|
// default is 'true'
|
|
24
24
|
show_preview?: boolean;
|
|
25
25
|
// duration in seconds for how long to show preview, default is 7 seconds
|
|
26
|
-
show_duration_sec?: number;
|
|
26
|
+
show_duration_sec?: number | null;
|
|
27
27
|
// indicator if the image in html_body can be zoomed out
|
|
28
28
|
// default is 'false'
|
|
29
29
|
enable_zoom_mode?: boolean;
|
|
@@ -62,6 +62,8 @@ export const InboxMessageBodyTransform = (item: InboxMessageBody): TInboxMessage
|
|
|
62
62
|
title: item.title,
|
|
63
63
|
preview_body: item.body,
|
|
64
64
|
custom_data: IntUtils.JsonOrText(item?.custom_data),
|
|
65
|
+
show_preview: item.show_preview,
|
|
66
|
+
show_duration_sec: item.show_duration_sec,
|
|
65
67
|
};
|
|
66
68
|
|
|
67
69
|
if (item.action === 'dp:inbox') {
|
|
@@ -486,6 +486,35 @@ export interface SAWTemplateUI {
|
|
|
486
486
|
*/
|
|
487
487
|
use_custom?: boolean;
|
|
488
488
|
|
|
489
|
+
/**
|
|
490
|
+
* Whether a custom mini-game fills the whole mini-game window instead of
|
|
491
|
+
* the default fixed-size frame (800×516 on desktop, 400×745 on mobile).
|
|
492
|
+
*
|
|
493
|
+
* Applies wherever the game is opened — a spin attempt shown to the user,
|
|
494
|
+
* a deep link, or `_smartico.miniGame()` in standalone or inline mode.
|
|
495
|
+
* The `fullscreen` option of `_smartico.miniGame()` overrides it per call.
|
|
496
|
+
*
|
|
497
|
+
* When `false` or omitted, the default frame size is used.
|
|
498
|
+
* Back-Office label: _"Standalone full screen"_.
|
|
499
|
+
*/
|
|
500
|
+
standalone_fullscreen?: boolean;
|
|
501
|
+
|
|
502
|
+
/**
|
|
503
|
+
* Width of the custom mini-game frame on desktop when opened standalone or inline,
|
|
504
|
+
* as a CSS size (`800px`, `100%`, `90vw`; a bare number is treated as pixels).
|
|
505
|
+
* Empty or invalid values fall back to the default 800px. Ignored on mobile.
|
|
506
|
+
* Back-Office label: _"Standalone width"_.
|
|
507
|
+
*/
|
|
508
|
+
standalone_width?: string;
|
|
509
|
+
|
|
510
|
+
/**
|
|
511
|
+
* Height of the custom mini-game frame on desktop when opened standalone or inline,
|
|
512
|
+
* as a CSS size (`516px`, `100%`, `90vh`; a bare number is treated as pixels).
|
|
513
|
+
* Empty or invalid values fall back to the default 516px. Ignored on mobile.
|
|
514
|
+
* Back-Office label: _"Standalone height"_.
|
|
515
|
+
*/
|
|
516
|
+
standalone_height?: string;
|
|
517
|
+
|
|
489
518
|
/**
|
|
490
519
|
* Minutes for the Voyager seed window.
|
|
491
520
|
* The seed window is the range of seeds that can be used to generate the map.
|
|
@@ -1,12 +1,19 @@
|
|
|
1
|
-
import { IntUtils } from "../IntUtils";
|
|
2
1
|
import { AchievementAvailabilityStatus } from "./AchievementAvailabilityStatus";
|
|
3
2
|
import { AchievementStatus } from "./AchievementStatus";
|
|
4
3
|
import { UserAchievement } from "./UserAchievement";
|
|
5
4
|
import { UserAchievementTask } from "./UserAchievementTask";
|
|
6
5
|
import { BadgesTimeLimitStates } from "./BadgesTimeLimitStates";
|
|
7
6
|
|
|
8
|
-
type UserStateParamsKeys =
|
|
9
|
-
|
|
7
|
+
type UserStateParamsKeys =
|
|
8
|
+
| 'core_fav_game_top3' | 'core_fav_game_type_top3' | 'core_fav_game_provider_top3'
|
|
9
|
+
| 'core_fav_sport_type_top3' | 'core_fav_sport_league_top3'
|
|
10
|
+
| 'core_recommended_deposit_amount' | 'core_recommended_casino_bet_amount' | 'core_recommended_sport_bet_amount';
|
|
11
|
+
|
|
12
|
+
// tag -> favorites (top 3 arrays) that fill it; a task has at most one condition per tag (enforced in the BO)
|
|
13
|
+
const FAV_TAGS: [string, UserStateParamsKeys[]][] = [
|
|
14
|
+
['{{suggested_games}}', ['core_fav_game_top3', 'core_fav_game_type_top3', 'core_fav_game_provider_top3']],
|
|
15
|
+
['{{suggested_sport}}', ['core_fav_sport_type_top3', 'core_fav_sport_league_top3']],
|
|
16
|
+
];
|
|
10
17
|
const USER_STATE_PARAMS_KEYS_BET_AMOUNT: UserStateParamsKeys[] = [
|
|
11
18
|
'core_recommended_deposit_amount',
|
|
12
19
|
'core_recommended_casino_bet_amount',
|
|
@@ -212,64 +219,47 @@ export class MissionUtils {
|
|
|
212
219
|
|
|
213
220
|
const userStateParams = (task.user_state_params || {});
|
|
214
221
|
const userStateOperator = task.task_public_meta?.user_state_operations;
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
if (userStateParamsKeys.length === 0 || !userStateOperator) {
|
|
222
|
+
if (Object.keys(userStateParams).length === 0 || !userStateOperator) {
|
|
218
223
|
return result;
|
|
219
224
|
}
|
|
220
225
|
|
|
221
|
-
const
|
|
222
|
-
const operatorsPos = ['pos1', 'pos2', 'pos3'];
|
|
223
|
-
|
|
224
|
-
let suggestedGames: string = '';
|
|
225
|
-
let suggestedValue: string = '';
|
|
226
|
-
|
|
227
|
-
userStateParamsKeys.forEach((k: UserStateParamsKeys) => {
|
|
228
|
-
const operator = userStateOperator[k]?.op;
|
|
229
|
-
|
|
230
|
-
if (USER_STATE_PARAMS_KEYS_GAMES.includes(k)) {
|
|
231
|
-
if (operatorsMulti.includes(operator)) {
|
|
232
|
-
const value = userStateParams[k]?.filter(v => Boolean(v));
|
|
233
|
-
if (value && value.length > 0) {
|
|
234
|
-
suggestedGames = value.map((v: string) => {
|
|
235
|
-
const cleaned = v.replace(/_/g, ' ');
|
|
236
|
-
return toGameTitleCase(cleaned);
|
|
237
|
-
}).join(', ');
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
if (operatorsPos.includes(operator)) {
|
|
242
|
-
const value = userStateParams[k];
|
|
243
|
-
const pos = Number(operator.replace('pos', '')) - 1;
|
|
226
|
+
const formatFav = (v: string): string => toGameTitleCase(v.replace(/_/g, ' '));
|
|
244
227
|
|
|
245
|
-
|
|
246
|
-
|
|
228
|
+
// 'has' / '!has' -> all favorites, 'posN' -> the N-th one
|
|
229
|
+
const favValue = (k: UserStateParamsKeys): string => {
|
|
230
|
+
const values = userStateParams[k];
|
|
231
|
+
const operator: string = userStateOperator[k]?.op;
|
|
247
232
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
233
|
+
if (!Array.isArray(values)) {
|
|
234
|
+
return '';
|
|
235
|
+
}
|
|
251
236
|
|
|
252
|
-
|
|
253
|
-
|
|
237
|
+
if (operator === 'has' || operator === '!has') {
|
|
238
|
+
return values.filter(Boolean).map(formatFav).join(', ');
|
|
254
239
|
}
|
|
255
240
|
|
|
256
|
-
|
|
257
|
-
suggestedValue = userStateParams[k];
|
|
241
|
+
const pos = /^pos[1-3]$/.test(operator) ? values[Number(operator.substring(3)) - 1] : null;
|
|
258
242
|
|
|
259
|
-
|
|
260
|
-
|
|
243
|
+
return pos ? formatFav(pos) : '';
|
|
244
|
+
};
|
|
261
245
|
|
|
262
|
-
|
|
263
|
-
|
|
246
|
+
// split/join replaces every occurrence of the tag, not only the first one
|
|
247
|
+
const replaceTag = (tag: string, value: string) => {
|
|
248
|
+
if (value && result) {
|
|
249
|
+
result = result.split(tag).join(value);
|
|
264
250
|
}
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
FAV_TAGS.forEach(([tag, keys]) => {
|
|
254
|
+
replaceTag(tag, keys.map(favValue).find(Boolean));
|
|
265
255
|
});
|
|
266
256
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
257
|
+
const amountKey = USER_STATE_PARAMS_KEYS_BET_AMOUNT.find((k) => userStateParams[k]);
|
|
258
|
+
|
|
259
|
+
if (amountKey) {
|
|
260
|
+
const currencyFromTheTask = userStateParams.core_wallet_currency;
|
|
270
261
|
|
|
271
|
-
|
|
272
|
-
result = result.replace('{{suggested_value}}', suggestedValue);
|
|
262
|
+
replaceTag('{{suggested_value}}', `${userStateParams[amountKey]} ${currencySymbol || currencyFromTheTask || ''}`);
|
|
273
263
|
}
|
|
274
264
|
|
|
275
265
|
return result;
|
|
@@ -76,13 +76,13 @@ export const UserAchievementTransform = (items: UserAchievement[]): TMissionOrBa
|
|
|
76
76
|
if (missionName?.includes('{{suggested_') || missionSubHeader?.includes('{{suggested_') || missionDescription?.includes('{{suggested_')) {
|
|
77
77
|
r.achievementTasks.forEach(t => {
|
|
78
78
|
if (r.ach_public_meta.name?.includes('{{suggested_')) {
|
|
79
|
-
missionName = MissionUtils.replaceTagsFavMissionTask({ task: t, valueToReplace:
|
|
79
|
+
missionName = MissionUtils.replaceTagsFavMissionTask({ task: t, valueToReplace: missionName });
|
|
80
80
|
}
|
|
81
81
|
if (r.ach_public_meta.sub_header?.includes('{{suggested_')) {
|
|
82
|
-
missionSubHeader = MissionUtils.replaceTagsFavMissionTask({ task: t, valueToReplace:
|
|
82
|
+
missionSubHeader = MissionUtils.replaceTagsFavMissionTask({ task: t, valueToReplace: missionSubHeader });
|
|
83
83
|
}
|
|
84
84
|
if (r.ach_public_meta.description?.includes('{{suggested_')) {
|
|
85
|
-
missionDescription = MissionUtils.replaceTagsFavMissionTask({ task: t, valueToReplace:
|
|
85
|
+
missionDescription = MissionUtils.replaceTagsFavMissionTask({ task: t, valueToReplace: missionDescription });
|
|
86
86
|
}
|
|
87
87
|
});
|
|
88
88
|
}
|
package/src/SmarticoGlobal.ts
CHANGED
|
@@ -50,6 +50,24 @@ export interface SmarticoWidgetParams {
|
|
|
50
50
|
zoom?: number;
|
|
51
51
|
/** Force the mobile layout regardless of viewport. */
|
|
52
52
|
force_mobile?: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Custom mini-games only ({@link SmarticoGlobal.miniGame}): `true` fills the whole mini-game window,
|
|
55
|
+
* `false` keeps the default fixed-size frame. Overrides the template's "Standalone full screen" setting;
|
|
56
|
+
* when omitted, the template setting is used.
|
|
57
|
+
*/
|
|
58
|
+
fullscreen?: boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Custom mini-games only ({@link SmarticoGlobal.miniGame}): desktop width of the game frame as a CSS size
|
|
61
|
+
* (`1000px`, `100%`, `90vw`; a number is treated as pixels). Overrides the template's "Standalone width"
|
|
62
|
+
* and "Standalone full screen" settings. Ignored on mobile.
|
|
63
|
+
*/
|
|
64
|
+
frame_width?: string | number;
|
|
65
|
+
/**
|
|
66
|
+
* Custom mini-games only ({@link SmarticoGlobal.miniGame}): desktop height of the game frame as a CSS size
|
|
67
|
+
* (`600px`, `100%`, `90vh`; a number is treated as pixels). Overrides the template's "Standalone height"
|
|
68
|
+
* and "Standalone full screen" settings. Ignored on mobile.
|
|
69
|
+
*/
|
|
70
|
+
frame_height?: string | number;
|
|
53
71
|
}
|
|
54
72
|
|
|
55
73
|
/**
|
package/src/WSAPI/WSAPIInbox.ts
CHANGED
|
@@ -363,6 +363,16 @@ export class WSAPIInbox extends WSAPILeaderBoard {
|
|
|
363
363
|
* for safe execution — that helper handles URL vs deep-link
|
|
364
364
|
* routing.
|
|
365
365
|
*
|
|
366
|
+
* **Preview vs silent delivery**
|
|
367
|
+
* Every message belongs in your inbox list. `show_preview` decides
|
|
368
|
+
* whether it should also pop up briefly when it arrives:
|
|
369
|
+
* - `show_preview !== false` → show a preview popup for
|
|
370
|
+
* `show_duration_sec ?? 7` seconds.
|
|
371
|
+
* - `show_preview === false` → store it silently, with no popup.
|
|
372
|
+
* These fields are returned exactly as the operator configured them;
|
|
373
|
+
* a missing value means the default above, the same as the default
|
|
374
|
+
* Smartico UI.
|
|
375
|
+
*
|
|
366
376
|
* **Idempotency / Side effects**: safe. Read-only HTTP fetch.
|
|
367
377
|
*
|
|
368
378
|
* **UI guidance**: see [UI Guide — `getInboxMessageBody`](../../docs/ui/inbox/UIGuide_getInboxMessageBody.md).
|
|
@@ -388,6 +398,12 @@ export class WSAPIInbox extends WSAPILeaderBoard {
|
|
|
388
398
|
* console.log('[smartico] simple message — show preview_body + single CTA wired to:', body.action,
|
|
389
399
|
* '— execute via _smartico.dp(body.action)');
|
|
390
400
|
* }
|
|
401
|
+
*
|
|
402
|
+
* if (body.show_preview !== false) {
|
|
403
|
+
* console.log('[smartico] new message — show a preview popup for', body.show_duration_sec ?? 7, 'seconds');
|
|
404
|
+
* } else {
|
|
405
|
+
* console.log('[smartico] new message — store it in the inbox silently, no popup');
|
|
406
|
+
* }
|
|
391
407
|
* ```
|
|
392
408
|
*/
|
|
393
409
|
public async getInboxMessageBody(messageGuid: string): Promise<TInboxMessageBody> {
|
package/src/WSAPI/WSAPITypes.ts
CHANGED
|
@@ -1146,6 +1146,12 @@ export interface TInboxMessageBody {
|
|
|
1146
1146
|
/** Operator-defined custom data. The SDK auto-parses JSON-looking
|
|
1147
1147
|
* strings, so at runtime this is `any` despite the `string` type. */
|
|
1148
1148
|
custom_data?: string;
|
|
1149
|
+
/** Whether to show a short preview popup when the message arrives.
|
|
1150
|
+
* `false` means store it in the inbox silently; missing means `true`. */
|
|
1151
|
+
show_preview?: boolean;
|
|
1152
|
+
/** How long the preview popup stays visible, in seconds.
|
|
1153
|
+
* `null` or missing means 7 seconds. */
|
|
1154
|
+
show_duration_sec?: number | null;
|
|
1149
1155
|
}
|
|
1150
1156
|
|
|
1151
1157
|
/**
|