@smartico/public-api 0.0.386 → 0.0.387
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/README.md +1 -1
- package/dist/Avatars/AvatarCustomizeErrorCode.d.ts +7 -1
- package/dist/Avatars/AvatarCustomizeResponse.d.ts +16 -0
- package/dist/Avatars/index.d.ts +1 -0
- package/dist/Missions/UserAchievementTask.d.ts +4 -0
- package/dist/SmarticoAPI.d.ts +11 -0
- package/dist/WSAPI/WSAPIAvatars.d.ts +103 -0
- package/dist/WSAPI/WSAPITypes.d.ts +6 -2
- package/dist/index.js +260 -78
- package/dist/index.js.map +1 -1
- package/dist/index.modern.mjs +168 -6
- package/dist/index.modern.mjs.map +1 -1
- package/docs/SmarticoObject.md +15 -0
- package/docs/api/README.md +2 -0
- package/docs/api/classes/WSAPIAvatars.md +135 -0
- package/docs/api/classes/WSAPIClans.md +3 -5
- package/docs/api/documents/SmarticoObject.md +15 -0
- package/docs/api/enumerations/AvatarCustomizeErrorCode.md +21 -0
- package/docs/api/enumerations/JoinClanErrorCode.md +16 -17
- package/docs/api/interfaces/AvatarCustomizeResponse.md +31 -0
- package/docs/api/interfaces/TAvatarPrompt.md +2 -2
- package/docs/api/interfaces/TMissionOrBadgeTask.md +16 -0
- package/docs/api/interfaces/UserAchievementTask.md +16 -0
- package/docs/native/PROTOCOL.md +3 -1
- package/docs/ui/avatars/UIGuide_avatarsCustomize.md +69 -0
- package/package.json +1 -1
- package/src/Avatars/AvatarCustomizeErrorCode.ts +7 -5
- package/src/Avatars/AvatarCustomizeResponse.ts +17 -0
- package/src/Avatars/index.ts +1 -0
- package/src/Missions/UserAchievement.ts +2 -0
- package/src/Missions/UserAchievementTask.ts +4 -0
- package/src/SmarticoAPI.ts +53 -0
- package/src/WSAPI/WSAPIAvatars.ts +121 -0
- package/src/WSAPI/WSAPITypes.ts +6 -2
- package/tsconfig.json +3 -1
package/src/SmarticoAPI.ts
CHANGED
|
@@ -144,6 +144,7 @@ import { GetAvatarsListResponse, avatarDefinitionTransform } from './Avatars/Get
|
|
|
144
144
|
import { GetAvatarsCustomizedResponse, avatarCustomizedTransform } from './Avatars/GetAvatarsCustomizedResponse';
|
|
145
145
|
import { GetAvatarPromptsResponse, avatarPromptTransform } from './Avatars/GetAvatarPromptsResponse';
|
|
146
146
|
import { SetAvatarRequest, SetAvatarResponse } from './Avatars';
|
|
147
|
+
import { AvatarCustomizeResponse } from './Avatars/AvatarCustomizeResponse';
|
|
147
148
|
import { GetJackpotWinnersResponse, GetJackpotWinnersResponseTransform, JackpotWinnerHistory } from './Jackpots/GetJackpotWinnersResponse';
|
|
148
149
|
import { GetJackpotWinnersRequest } from './Jackpots/GetJackpotWinnersRequest';
|
|
149
150
|
import { GetJackpotEligibleGamesRequest } from './Jackpots/GetJackpotEligibleGamesRequest';
|
|
@@ -183,6 +184,7 @@ class SmarticoAPI {
|
|
|
183
184
|
private gamesApiUrl: string;
|
|
184
185
|
private baseRgApiParams: Record<string, string>;
|
|
185
186
|
public avatarDomain: string;
|
|
187
|
+
private avatarOriginDomain: string;
|
|
186
188
|
private envId: number;
|
|
187
189
|
|
|
188
190
|
private logger: ILogger;
|
|
@@ -220,6 +222,7 @@ class SmarticoAPI {
|
|
|
220
222
|
}
|
|
221
223
|
|
|
222
224
|
this.avatarDomain = SmarticoAPI.getAvatarUrl(label_api_key || options.tracker?.label_api_key);
|
|
225
|
+
this.avatarOriginDomain = SmarticoAPI.getAvatarOriginUrl(label_api_key || options.tracker?.label_api_key);
|
|
223
226
|
|
|
224
227
|
this.label_api_key = SmarticoAPI.getCleanLabelApiKey(label_api_key);
|
|
225
228
|
}
|
|
@@ -292,6 +295,10 @@ class SmarticoAPI {
|
|
|
292
295
|
return SmarticoAPI.replaceSmrDomainsWithCloudfront(avatarUrl);
|
|
293
296
|
}
|
|
294
297
|
|
|
298
|
+
public static getAvatarOriginUrl(label_api_key: string): string {
|
|
299
|
+
return AVATAR_DOMAIN.replace('{ENV_ID}', SmarticoAPI.getEnvDnsSuffix(label_api_key));
|
|
300
|
+
}
|
|
301
|
+
|
|
295
302
|
private async send<T>(message: any, expectCID?: ClassId, force_language?: string): Promise<T> {
|
|
296
303
|
if (this.logCIDs.includes(message.cid)) {
|
|
297
304
|
this.logger.info('REQ', message);
|
|
@@ -1438,6 +1445,31 @@ class SmarticoAPI {
|
|
|
1438
1445
|
}
|
|
1439
1446
|
}
|
|
1440
1447
|
|
|
1448
|
+
private async sendAvatarApi<T>({ method, body }: { method: string, body: Record<string, any> }): Promise<T> {
|
|
1449
|
+
if (!this.tracker) {
|
|
1450
|
+
throw new Error(`Avatar APIs are not available in the visitor mode`);
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
const url = `${this.avatarOriginDomain}/${method}`;
|
|
1454
|
+
|
|
1455
|
+
try {
|
|
1456
|
+
const response = await fetch(url, {
|
|
1457
|
+
method: 'POST',
|
|
1458
|
+
headers: {
|
|
1459
|
+
'Accept': 'application/json',
|
|
1460
|
+
'Content-Type': 'application/json',
|
|
1461
|
+
},
|
|
1462
|
+
body: JSON.stringify(body),
|
|
1463
|
+
});
|
|
1464
|
+
|
|
1465
|
+
const data = await response.json();
|
|
1466
|
+
return SmarticoAPI.replaceSmrDomainsWithCloudfront<T>(data);
|
|
1467
|
+
} catch (e) {
|
|
1468
|
+
this.logger.error(`Failed to call avatar API: ${method}`, { url, error: e.message });
|
|
1469
|
+
throw new Error(`Failed to call avatar API: ${method}. ${e.message}`);
|
|
1470
|
+
}
|
|
1471
|
+
}
|
|
1472
|
+
|
|
1441
1473
|
public async gpGetActiveRounds(saw_template_id: number): Promise<GamesApiResponse<GamePickRound[]>> {
|
|
1442
1474
|
const params = {
|
|
1443
1475
|
ext_game_id: saw_template_id,
|
|
@@ -1539,6 +1571,27 @@ class SmarticoAPI {
|
|
|
1539
1571
|
return await this.send<SetAvatarResponse>(message, ClassId.CLIENT_SET_AVATAR_RESPONSE);
|
|
1540
1572
|
}
|
|
1541
1573
|
|
|
1574
|
+
public async avatarsCustomize(params: {
|
|
1575
|
+
label_id: number;
|
|
1576
|
+
user_id: number;
|
|
1577
|
+
prompt_id: number;
|
|
1578
|
+
avatar_url: string;
|
|
1579
|
+
avatar_real_id: number;
|
|
1580
|
+
}): Promise<AvatarCustomizeResponse> {
|
|
1581
|
+
return this.sendAvatarApi<AvatarCustomizeResponse>({
|
|
1582
|
+
method: 'avatar-customize',
|
|
1583
|
+
body: {
|
|
1584
|
+
label_id: params.label_id,
|
|
1585
|
+
user_id: params.user_id,
|
|
1586
|
+
user_ext_id: this.tracker?.getExtUserId(),
|
|
1587
|
+
brand_key: this.brand_api_key || this.tracker?.params?.brand_key,
|
|
1588
|
+
prompt_id: params.prompt_id,
|
|
1589
|
+
avatar_url: params.avatar_url,
|
|
1590
|
+
avatar_real_id: params.avatar_real_id,
|
|
1591
|
+
},
|
|
1592
|
+
});
|
|
1593
|
+
}
|
|
1594
|
+
|
|
1542
1595
|
public async avatarsGetListT(user_ext_id: string): Promise<TAvatarDefinition[]> {
|
|
1543
1596
|
return avatarDefinitionTransform((await this.avatarsGetList(user_ext_id)).avatars ?? [], this.avatarDomain);
|
|
1544
1597
|
}
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
onUpdateContextKey,
|
|
11
11
|
} from './WSAPIBase';
|
|
12
12
|
import { WSAPIMiniGames } from './WSAPIMiniGames';
|
|
13
|
+
import { AvatarCustomizeResponse } from '../Avatars/AvatarCustomizeResponse';
|
|
13
14
|
|
|
14
15
|
/** @group Avatars */
|
|
15
16
|
export class WSAPIAvatars extends WSAPIMiniGames {
|
|
@@ -342,4 +343,124 @@ export class WSAPIAvatars extends WSAPIMiniGames {
|
|
|
342
343
|
err_message: r.errMsg,
|
|
343
344
|
};
|
|
344
345
|
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Generates an AI-customized variant of a base avatar by applying an
|
|
349
|
+
* operator-defined style prompt, returning the CDN URL of the result.
|
|
350
|
+
* This is a paid, generate-only step: it does NOT change the user's
|
|
351
|
+
* active avatar — pass the returned `cdn_url` to {@link setAvatar} to
|
|
352
|
+
* activate it.
|
|
353
|
+
*
|
|
354
|
+
* @remarks
|
|
355
|
+
* **Preconditions**
|
|
356
|
+
* - Authenticated session required; not available in visitor mode (throws).
|
|
357
|
+
* - All five fields are mandatory — the SDK throws synchronously
|
|
358
|
+
* (`Error("<field> is required")`) if any is missing or zero.
|
|
359
|
+
* - `prompt_id` must be one of the prompts from {@link getAvatarPrompts};
|
|
360
|
+
* `avatar_url` / `avatar_real_id` identify the base avatar to style.
|
|
361
|
+
*
|
|
362
|
+
* **Cost**
|
|
363
|
+
* Each generation costs the currency the operator configured on the
|
|
364
|
+
* chosen prompt (points, gems, or diamonds — some prompts are free; read
|
|
365
|
+
* `cost_currency_type_id` / `cost_value` from the {@link getAvatarPrompts}
|
|
366
|
+
* entry to gate the UI before calling). The cost is charged only on
|
|
367
|
+
* success; if the user can't afford it the call fails with `errCode -1`
|
|
368
|
+
* and nothing is generated or charged.
|
|
369
|
+
*
|
|
370
|
+
* **Latency**
|
|
371
|
+
* Generation runs server-side AI image synthesis and is synchronous from
|
|
372
|
+
* the caller's side — expect several seconds (roughly 5–20 s) before the
|
|
373
|
+
* promise resolves. There is no SDK cache and no push/subscription; show
|
|
374
|
+
* a loading state for the full duration and disable the trigger to
|
|
375
|
+
* prevent duplicate submissions.
|
|
376
|
+
*
|
|
377
|
+
* **Result & error codes**
|
|
378
|
+
* On success the result has `cdn_url` set; on failure it has `errCode` /
|
|
379
|
+
* `errMessage` set and no `cdn_url`. Branch on `errCode` — the generic
|
|
380
|
+
* message is fixed text, not cause-specific:
|
|
381
|
+
* - `12001` (`AvatarCustomizeErrorCode.AVATAR_USER_LIMIT`) — the user hit
|
|
382
|
+
* their monthly per-user generation cap. Nothing is generated or charged.
|
|
383
|
+
* - `12002` (`AvatarCustomizeErrorCode.AVATAR_LABEL_LIMIT`) — the brand's
|
|
384
|
+
* shared monthly pool is exhausted. Nothing is generated or charged;
|
|
385
|
+
* surface a "try again later" message.
|
|
386
|
+
* - `-1` — generic failure: insufficient balance, an unavailable prompt,
|
|
387
|
+
* or a generation error. Nothing is charged. Allow the user to retry.
|
|
388
|
+
*
|
|
389
|
+
* Both monthly caps are operator-configured and reset at the start of
|
|
390
|
+
* each calendar month.
|
|
391
|
+
*
|
|
392
|
+
* **Side effects (on success)**
|
|
393
|
+
* The generated variant is persisted to the user's customization history
|
|
394
|
+
* and counts toward the monthly caps **whether or not** it is later
|
|
395
|
+
* activated — generation is not reversible. The SDK clears the
|
|
396
|
+
* {@link getAvatarsCustomized} cache so the next call surfaces the new
|
|
397
|
+
* variant. The user's active avatar is unchanged until you call
|
|
398
|
+
* {@link setAvatar} with the returned `cdn_url`.
|
|
399
|
+
*
|
|
400
|
+
* **Idempotency**: not idempotent — each successful call generates (and
|
|
401
|
+
* charges for) a new variant. Guard the call site against double-clicks.
|
|
402
|
+
*
|
|
403
|
+
* **UI guidance**: see [UI Guide — `avatarsCustomize`](../../docs/ui/avatars/UIGuide_avatarsCustomize.md).
|
|
404
|
+
*
|
|
405
|
+
* **Visitor mode**: not supported (throws).
|
|
406
|
+
*
|
|
407
|
+
* @param props.label_id Numeric Smartico label (brand) ID the user belongs to.
|
|
408
|
+
* @param props.user_id Numeric Smartico user ID.
|
|
409
|
+
* @param props.prompt_id Style-prompt ID (`prompt_id`) from {@link getAvatarPrompts}.
|
|
410
|
+
* @param props.avatar_url CDN URL of the base avatar to customize.
|
|
411
|
+
* @param props.avatar_real_id `avatar_real_id` of the base avatar.
|
|
412
|
+
* @returns {@link AvatarCustomizeResponse} — `cdn_url` set on success;
|
|
413
|
+
* `errCode` / `errMessage` set on failure.
|
|
414
|
+
*
|
|
415
|
+
* @example
|
|
416
|
+
* ```ts
|
|
417
|
+
* // label_id / user_id identify the Smartico user being customized.
|
|
418
|
+
* const prompts = await window._smartico.api.getAvatarPrompts();
|
|
419
|
+
* const prompt = prompts[0];
|
|
420
|
+
*
|
|
421
|
+
* console.log('[smartico] generating avatar — show a spinner for ~5-20s and disable the Generate button');
|
|
422
|
+
* const result = await window._smartico.api.avatarsCustomize({
|
|
423
|
+
* label_id,
|
|
424
|
+
* user_id,
|
|
425
|
+
* prompt_id: prompt.prompt_id,
|
|
426
|
+
* avatar_url: baseAvatar.avatar_url,
|
|
427
|
+
* avatar_real_id: baseAvatar.avatar_real_id,
|
|
428
|
+
* });
|
|
429
|
+
*
|
|
430
|
+
* if (result.cdn_url) {
|
|
431
|
+
* console.log('[smartico] generation succeeded — preview this URL, then call setAvatar to apply it:', result.cdn_url);
|
|
432
|
+
* // await window._smartico.api.setAvatar({ avatar_url: result.cdn_url, avatar_real_id: baseAvatar.avatar_real_id });
|
|
433
|
+
* } else if (result.errCode === 12001) {
|
|
434
|
+
* console.error('[smartico] user monthly limit reached — show "you have used all your custom avatars this month"');
|
|
435
|
+
* } else if (result.errCode === 12002) {
|
|
436
|
+
* console.error('[smartico] brand monthly pool exhausted — show "custom avatars are unavailable right now, try later"');
|
|
437
|
+
* } else {
|
|
438
|
+
* console.error('[smartico] generation failed (e.g. not enough balance) — let the user retry:', result.errMessage);
|
|
439
|
+
* }
|
|
440
|
+
* ```
|
|
441
|
+
*/
|
|
442
|
+
public async avatarsCustomize(props: {
|
|
443
|
+
label_id: number;
|
|
444
|
+
user_id: number;
|
|
445
|
+
prompt_id: number;
|
|
446
|
+
avatar_url: string;
|
|
447
|
+
avatar_real_id: number;
|
|
448
|
+
}): Promise<AvatarCustomizeResponse> {
|
|
449
|
+
const required: (keyof typeof props)[] = ['label_id', 'user_id', 'prompt_id', 'avatar_url', 'avatar_real_id'];
|
|
450
|
+
for (const field of required) {
|
|
451
|
+
if (!props[field]) {
|
|
452
|
+
throw new Error(`${field} is required`);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
const r = await this.api.avatarsCustomize(props);
|
|
457
|
+
|
|
458
|
+
// On success a new variant is persisted server-side — drop the cached
|
|
459
|
+
// list so the next getAvatarsCustomized() surfaces it.
|
|
460
|
+
if (r.cdn_url) {
|
|
461
|
+
OCache.clear(ECacheContext.WSAPI, onUpdateContextKey.AvatarsCustomized);
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
return r;
|
|
465
|
+
}
|
|
345
466
|
}
|
package/src/WSAPI/WSAPITypes.ts
CHANGED
|
@@ -953,6 +953,10 @@ export interface TMissionOrBadgeTask {
|
|
|
953
953
|
progress: number;
|
|
954
954
|
/** Reward for completing the task in points */
|
|
955
955
|
points_reward: number;
|
|
956
|
+
/** Reward for completing the task in gems */
|
|
957
|
+
gems_reward?: number;
|
|
958
|
+
/** Reward for completing the task in diamonds */
|
|
959
|
+
diamonds_reward?: number;
|
|
956
960
|
/** This is the total number of times the user needs to execute to complete task. e.g. he needs to bet 100 times. Here will be 100 */
|
|
957
961
|
execution_count_expected?: number;
|
|
958
962
|
/** This is the number of times the user has executed 'activity' of the task. e.g. he bet 5 times out of 100. Here will be 5 */
|
|
@@ -1780,9 +1784,9 @@ export interface TAvatarPrompt {
|
|
|
1780
1784
|
name: string;
|
|
1781
1785
|
/** Absolute CDN URL of the prompt's preview icon. */
|
|
1782
1786
|
icon_url: string;
|
|
1783
|
-
/** Currency used to pay for the customization. `0` = points, `1` = gems, `2` = diamonds. */
|
|
1787
|
+
/** Currency used to pay for the customization. `0` = points, `1` = gems, `2` = diamonds, `3` = free. A `cost_value` of `0` is also free. */
|
|
1784
1788
|
cost_currency_type_id: number;
|
|
1785
|
-
/** Cost amount in the currency named by `cost_currency_type_id`. */
|
|
1789
|
+
/** Cost amount in the currency named by `cost_currency_type_id`. `0` = free. */
|
|
1786
1790
|
cost_value: number;
|
|
1787
1791
|
}
|
|
1788
1792
|
|
package/tsconfig.json
CHANGED
|
@@ -90,7 +90,9 @@
|
|
|
90
90
|
"src/Tournaments/GetClanTournamentPlayersResponse.ts",
|
|
91
91
|
"src/Avatars/AvatarDefinition.ts",
|
|
92
92
|
"src/Avatars/AvatarCustomized.ts",
|
|
93
|
-
"src/Avatars/AvatarPrompt.ts"
|
|
93
|
+
"src/Avatars/AvatarPrompt.ts",
|
|
94
|
+
"src/Avatars/AvatarCustomizeResponse.ts",
|
|
95
|
+
"src/Avatars/AvatarCustomizeErrorCode.ts"
|
|
94
96
|
],
|
|
95
97
|
"out": "docs/api",
|
|
96
98
|
"projectDocuments": ["docs/SmarticoObject.md", "docs/Callbacks.md", "docs/Transforms.md"],
|