@smartico/public-api 0.0.47 → 0.0.49

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.
@@ -0,0 +1,167 @@
1
+ # Interface: TMissionOrBadge
2
+
3
+ TMissionOrBadge interface describes the information of mission or badge defined in the system
4
+
5
+ ## Properties
6
+
7
+ ### id
8
+
9
+ • **id**: `number`
10
+
11
+ ID of the mission or badge
12
+
13
+ ___
14
+
15
+ ### type
16
+
17
+ • **type**: ``"mission"`` \| ``"badge"``
18
+
19
+ Type of entity. Can be 'mission' or 'badge'
20
+
21
+ ___
22
+
23
+ ### name
24
+
25
+ • **name**: `string`
26
+
27
+ Name of the mission or badge, translated to the user language
28
+
29
+ ___
30
+
31
+ ### desription
32
+
33
+ • **desription**: `string`
34
+
35
+ Description of the mission or badge, translated to the user language
36
+
37
+ ___
38
+
39
+ ### reward
40
+
41
+ • **reward**: `string`
42
+
43
+ Description of the mission reward if defined
44
+
45
+ ___
46
+
47
+ ### image
48
+
49
+ • **image**: `string`
50
+
51
+ URL of the image of the mission or badge
52
+
53
+ ___
54
+
55
+ ### is\_completed
56
+
57
+ • **is\_completed**: `boolean`
58
+
59
+ Indicator if the mission is completed or badge is granted
60
+
61
+ ___
62
+
63
+ ### is\_locked
64
+
65
+ • **is\_locked**: `boolean`
66
+
67
+ Indicator if the mission is locked. Means that it's visible to the user, but he cannot progress in it until it's unlocked.
68
+ Mission may optionally contain the explanation of what should be done to unlock it in the unlock_mission_description property
69
+
70
+ ___
71
+
72
+ ### unlock\_mission\_description
73
+
74
+ • **unlock\_mission\_description**: `string`
75
+
76
+ Optional explaination of what should be done to unlock the mission
77
+
78
+ ___
79
+
80
+ ### is\_requires\_optin
81
+
82
+ • **is\_requires\_optin**: `boolean`
83
+
84
+ Indicator if the mission requires opt-in. Means that user should explicitly opt-in to the mission in order to start progressing in it
85
+
86
+ ___
87
+
88
+ ### is\_opted\_in
89
+
90
+ • **is\_opted\_in**: `boolean`
91
+
92
+ Indicator if the user opted-in to the mission
93
+
94
+ ___
95
+
96
+ ### time\_limit\_ms
97
+
98
+ • **time\_limit\_ms**: `number`
99
+
100
+ The amount of time in milliseconds that user has to complete the mission
101
+
102
+ ___
103
+
104
+ ### dt\_start
105
+
106
+ • **dt\_start**: `number`
107
+
108
+ The date when the mission was started, relevant for the time limited missions
109
+
110
+ ___
111
+
112
+ ### progress
113
+
114
+ • **progress**: `number`
115
+
116
+ The progress of the mission in percents calculated as the aggregated relative percentage of all tasks
117
+
118
+ ___
119
+
120
+ ### cta\_action
121
+
122
+ • **cta\_action**: `string`
123
+
124
+ The action that should be performed when user clicks on the mission or badge
125
+ Can be URL or deep link, e.g. 'dp:deposit'. The most safe to execute CTA is to pass it to _smartico.do(cta_action);
126
+ The 'dp' function will handle the CTA and will execute it in the most safe way
127
+
128
+ ___
129
+
130
+ ### cta\_text
131
+
132
+ • **cta\_text**: `string`
133
+
134
+ The text of the CTA button, e.g. 'Make a deposit'
135
+
136
+ ___
137
+
138
+ ### custom\_section\_id
139
+
140
+ • **custom\_section\_id**: `number`
141
+
142
+ The ID of the custom section where the mission or badge is assigned
143
+ The list of custom sections can be retrieved using _smartico.api.getCustomSections() method (TODO-API)
144
+
145
+ ___
146
+
147
+ ### only\_in\_custom\_section
148
+
149
+ • **only\_in\_custom\_section**: `boolean`
150
+
151
+ The indicator if the mission or badge is visible only in the custom section and should be hidden from the main overview of missions/badges
152
+
153
+ ___
154
+
155
+ ### custom\_data
156
+
157
+ • **custom\_data**: `any`
158
+
159
+ The custom data of the mission or badge defined by operator. Can be a JSON object, string or number
160
+
161
+ ___
162
+
163
+ ### tasks
164
+
165
+ • **tasks**: [`TMissionOrBadgeTask`](TMissionOrBadgeTask.md)[]
166
+
167
+ The list of tasks of the mission or badge
@@ -0,0 +1,35 @@
1
+ # Interface: TMissionOrBadgeTask
2
+
3
+ TMissionOrBadgeTask interface describes the information of tasks that belings to mission or badge. See also TMissionOrBadge
4
+
5
+ ## Properties
6
+
7
+ ### id
8
+
9
+ • **id**: `number`
10
+
11
+ ID of the task
12
+
13
+ ___
14
+
15
+ ### name
16
+
17
+ • **name**: `string`
18
+
19
+ Name of the task, translated to the user language
20
+
21
+ ___
22
+
23
+ ### is\_completed
24
+
25
+ • **is\_completed**: `boolean`
26
+
27
+ Indicator if the task is completed
28
+
29
+ ___
30
+
31
+ ### progress
32
+
33
+ • **progress**: `number`
34
+
35
+ The progress of the task in percents
@@ -0,0 +1,81 @@
1
+ # Interface: TUserProfile
2
+
3
+ TUser interface describes the information of the user
4
+ The user object is returned by _smartico.api.getUserProfile() method.
5
+ If you want to track the changes of the user profile, you can subscribe to the callback in the following way
6
+ _smartico.on('props_change', () => console.log(_smartico.api.getUserProfile()) );
7
+
8
+ ## Properties
9
+
10
+ ### core\_user\_language
11
+
12
+ • **core\_user\_language**: `string`
13
+
14
+ The language of the user
15
+
16
+ ___
17
+
18
+ ### ach\_points\_balance
19
+
20
+ • **ach\_points\_balance**: `number`
21
+
22
+ The current points balance that user can use in the Store, Mini-games, Tournaments, etc..
23
+
24
+ ___
25
+
26
+ ### ach\_points\_ever
27
+
28
+ • **ach\_points\_ever**: `number`
29
+
30
+ The amount of points that user collected in total
31
+
32
+ ___
33
+
34
+ ### core\_public\_tags
35
+
36
+ • **core\_public\_tags**: `string`[]
37
+
38
+ The array of the public tags set on the user object.
39
+ They can be treated as server-based cookies.
40
+ You can set tags using following method _smartico.event('core_public_tags_update', { core_public_tags: ['A', 'B'] } );
41
+ And then you can check for the tags
42
+
43
+ ___
44
+
45
+ ### ach\_level\_current\_id
46
+
47
+ • `Optional` **ach\_level\_current\_id**: `number`
48
+
49
+ The ID of the current level of the user
50
+
51
+ ___
52
+
53
+ ### core\_is\_test\_account
54
+
55
+ • `Optional` **core\_is\_test\_account**: `boolean`
56
+
57
+ The indicator if user is marked as test user
58
+
59
+ ___
60
+
61
+ ### avatar\_url
62
+
63
+ • `Optional` **avatar\_url**: `string`
64
+
65
+ The URL to the user avatar
66
+
67
+ ___
68
+
69
+ ### public\_username
70
+
71
+ • `Optional` **public\_username**: `string`
72
+
73
+ The username of current user
74
+
75
+ ___
76
+
77
+ ### core\_inbox\_unread\_count
78
+
79
+ • `Optional` **core\_inbox\_unread\_count**: `number`
80
+
81
+ THe number of unread inbox messages
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smartico/public-api",
3
- "version": "0.0.47",
3
+ "version": "0.0.49",
4
4
  "description": "Smartico public API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/IntUtils.ts CHANGED
@@ -32,6 +32,25 @@ class IntUtils {
32
32
  return v;
33
33
  }
34
34
 
35
+ public static JsonOrText = (str: string): any => {
36
+ if (str && str.includes && (str.includes('{') || str.includes('['))) {
37
+ try {
38
+ return JSON.parse(str)
39
+ } catch (e) {
40
+ return str;
41
+ }
42
+ }
43
+ return str;
44
+ }
45
+
46
+ // public static wsTimeToEpoch = (time: string): number => {
47
+ // if (time) {
48
+ // return moment.utc(time, "DD/MM/YYYY HH:mm:ss").valueOf()
49
+ // } else {
50
+ // return null
51
+ // }
52
+ // }
53
+
35
54
  }
36
55
 
37
56
 
@@ -1,7 +1,23 @@
1
1
  import { ProtocolResponse } from "../Base/ProtocolResponse";
2
+ import { TLevel } from "../WSAPI/WSAPITypes";
2
3
  import { Level } from "./Level";
3
4
 
4
5
  export interface GetLevelMapResponse extends ProtocolResponse {
5
6
 
6
7
  levels: Level[];
7
8
  }
9
+
10
+
11
+ export const GetLevelMapResponseTransform = (levels: GetLevelMapResponse): TLevel[] => {
12
+
13
+ return levels?.levels.map((l => ({
14
+ id: l.level_id,
15
+ name: l.level_public_meta.name,
16
+ description: l.level_public_meta.description,
17
+ image: l.level_public_meta.image_url,
18
+ required_points: l.required_points,
19
+ visibility_points: parseInt(l.level_public_meta.visibility_points as any),
20
+ required_level_counter_1: l.required_level_counter_1,
21
+ required_level_counter_2: l.required_level_counter_2,
22
+ })));
23
+ }
@@ -1,6 +1,9 @@
1
1
 
2
+ import { IntUtils } from "../IntUtils";
3
+ import { TMissionOrBadge } from "../WSAPI/WSAPITypes";
2
4
  import { AchievementPublicMeta } from "./AchievementPublicMeta";
3
5
  import { AchievementStatus } from "./AchievementStatus";
6
+ import { AchievementTaskType } from "./AchievementTaskType";
4
7
  import { AchievementType } from "./AchievementType";
5
8
  import { UserAchievementTask } from "./UserAchievementTask";
6
9
 
@@ -14,6 +17,7 @@ export interface UserAchievement {
14
17
  requiresOptin?: boolean;
15
18
  isOptedIn?: boolean;
16
19
  start_date?: string; // time when mission unlocked or opted-in. Needed to calculated "remaining time" in case time_limit_ms is set
20
+ start_date_ts?: number;
17
21
  time_limit_ms?: number;
18
22
  progress?: number;
19
23
  complete_date?: string;
@@ -23,3 +27,38 @@ export interface UserAchievement {
23
27
  ach_status_id?: AchievementStatus;
24
28
  }
25
29
 
30
+ export const UserAchievementTransform = (items: UserAchievement[]): TMissionOrBadge[] => {
31
+
32
+ return items.filter( r => r.ach_id >= 1).map( r => (
33
+ {
34
+ id: r.ach_id,
35
+ name: r.ach_public_meta.name,
36
+ desription: r.ach_public_meta.description,
37
+ unlock_mission_description: r.ach_public_meta.unlock_mission_description,
38
+ image: r.ach_public_meta.image_url,
39
+ is_completed: r.isCompleted,
40
+ is_locked: r.isLocked,
41
+ is_requires_optin: r.requiresOptin,
42
+ is_opted_in: r.isOptedIn,
43
+ time_limit_ms: r.time_limit_ms,
44
+ dt_start: r.start_date_ts,
45
+ reward: r.ach_public_meta.reward,
46
+ progress: r.progress,
47
+ type: r.ach_type_id === AchievementType.Mission ? 'mission' : 'badge',
48
+ cta_action: r.ach_public_meta.cta_action,
49
+ cta_text: r.ach_public_meta.cta_text,
50
+ custom_section_id: r.ach_public_meta.custom_section_id,
51
+ only_in_custom_section: r.ach_public_meta.only_in_custom_section,
52
+ custom_data: IntUtils.JsonOrText(r.ach_public_meta.custom_data),
53
+ tasks: (r.achievementTasks || [])
54
+ .filter( t => t.task_type_id === AchievementTaskType.CompleteAchievement)
55
+ .map( t => ({
56
+ id: t.task_id,
57
+ name: t.task_public_meta?.name,
58
+ is_completed: t.isCompleted,
59
+ progress: t.userProgress,
60
+ }))
61
+ }
62
+ ));
63
+ }
64
+
@@ -12,21 +12,27 @@ import { GetLabelInfoResponse } from './Core/GetLabelInfoResponse';
12
12
  import { GetLabelInfoRequest } from './Core/GetLabelInfoRequest';
13
13
  import { GetInboxMessagesRequest, GetInboxMessagesResponse } from './Inbox';
14
14
  import { GetStoreItemsResponse } from './Store';
15
- import { AchievementType, GetAchievementMapRequest, GetAchievementMapResponse } from './Missions';
15
+ import { AchievementType, GetAchievementMapRequest, GetAchievementMapResponse, UserAchievementTransform } from './Missions';
16
16
  import { GetTournamentInfoRequest, GetTournamentInfoResponse, GetTournamentsRequest, GetTournamentsResponse } from './Tournaments';
17
17
  import { GetLeaderBoardsRequest, GetLeaderBoardsResponse, LeaderBoardDetails, LeaderBoardPeriodType } from "./Leaderboard";
18
- import { GetLevelMapResponse } from "./Level";
18
+ import { GetLevelMapResponse, GetLevelMapResponseTransform } from "./Level";
19
19
  import { WSAPI } from "./WSAPI/WSAPI";
20
+ import { TLevel, TMissionOrBadge } from "./WSAPI/WSAPITypes";
20
21
 
21
22
  const PUBLIC_API_URL = 'https://papi{ENV_ID}.smartico.ai/services/public';
22
23
  const C_SOCKET_PROD = 'wss://api{ENV_ID}.smartico.ai/websocket/services';
23
24
  const AVATAR_DOMAIN = 'https://img{ENV_ID}.smr.vc';
24
25
  const DEFAULT_LANG_EN = "EN";
25
26
 
27
+ interface Tracker {
28
+ label_api_key: string;
29
+ userPublicProps: any;
30
+ }
26
31
  interface IOptions {
27
32
  logger?: ILogger;
28
33
  logCIDs?: ClassId[];
29
34
  logHTTPTiming?: boolean;
35
+ tracker?: Tracker;
30
36
  }
31
37
 
32
38
  type MessageSender = (message: any, publicApuUrl?: string, expectCID?: ClassId) => Promise<any>;
@@ -37,11 +43,12 @@ class SmarticoAPI {
37
43
  private publicUrl: string;
38
44
  private wsUrl: string;
39
45
  private partnerUrl: string;
40
- private avatarDomain: string;
46
+ public avatarDomain: string;
41
47
 
42
48
  private logger: ILogger;
43
49
  private logCIDs: ClassId[];
44
50
  private logHTTPTiming: boolean;
51
+ public tracker?: Tracker;
45
52
 
46
53
  public constructor(private label_api_key: string, private brand_api_key: string, private messageSender: MessageSender, options: IOptions = {}) {
47
54
 
@@ -53,11 +60,12 @@ class SmarticoAPI {
53
60
 
54
61
  this.logCIDs = options.logCIDs || [];
55
62
  this.logHTTPTiming = options.logHTTPTiming || false;
63
+ this.tracker = options.tracker;
56
64
 
57
65
  this.publicUrl = SmarticoAPI.getPublicUrl(label_api_key);
58
66
  this.wsUrl = SmarticoAPI.getPublicWsUrl(label_api_key);
59
67
 
60
- this.avatarDomain = SmarticoAPI.getAvatarUrl(label_api_key);
68
+ this.avatarDomain = SmarticoAPI.getAvatarUrl(label_api_key || options.tracker?.label_api_key);
61
69
 
62
70
  this.label_api_key = SmarticoAPI.getCleanLabelApiKey(label_api_key);
63
71
 
@@ -195,7 +203,7 @@ class SmarticoAPI {
195
203
  areas
196
204
  });
197
205
 
198
- const trBase = await this.send<GetTranslationsResponse>(tsBaseRQ);
206
+ const trBase = await this.send<GetTranslationsResponse>(tsBaseRQ, ClassId.GET_TRANSLATIONS_RESPONSE);
199
207
 
200
208
  if (lang_code !== DEFAULT_LANG_EN) {
201
209
  const trUserRQ = this.buildMessage<GetTranslationsRequest, GetTranslationsResponse>(user_ext_id, ClassId.GET_TRANSLATIONS_REQUEST, {
@@ -204,7 +212,7 @@ class SmarticoAPI {
204
212
  areas
205
213
  });
206
214
 
207
- const trUser = await this.send<GetTranslationsResponse>(trUserRQ);
215
+ const trUser = await this.send<GetTranslationsResponse>(trUserRQ, ClassId.GET_TRANSLATIONS_RESPONSE);
208
216
 
209
217
  Object.keys(trUser?.translations ?? {}).forEach( k => {
210
218
  trBase.translations[k] = trUser.translations[k];
@@ -256,7 +264,7 @@ class SmarticoAPI {
256
264
 
257
265
  const message = this.buildMessage<SAWGetTemplatesRequest, SAWGetTemplatesResponse>(user_ext_id, ClassId.SAW_GET_SPINS_REQUEST, lang ? { force_language: lang, is_visitor_mode } : { is_visitor_mode });
258
266
 
259
- const response = await this.send<SAWGetTemplatesResponse>(message);
267
+ const response = await this.send<SAWGetTemplatesResponse>(message, ClassId.SAW_GET_SPINS_RESPONSE);
260
268
 
261
269
  if (response && response.templates) {
262
270
  response.templates.forEach(t => {
@@ -314,31 +322,35 @@ class SmarticoAPI {
314
322
  offset
315
323
  });
316
324
 
317
- return await this.send<GetInboxMessagesResponse>(message);
325
+ return await this.send<GetInboxMessagesResponse>(message, ClassId.GET_INBOX_MESSAGES_RESPONSE);
318
326
 
319
327
  }
320
328
 
321
329
  public async storeGetItems(user_ext_id: string): Promise<GetStoreItemsResponse> {
322
330
 
323
331
  const message = this.buildMessage<any, GetStoreItemsResponse>(user_ext_id, ClassId.GET_SHOP_ITEMS_REQUEST);
324
- return await this.send<GetStoreItemsResponse>(message);
332
+ return await this.send<GetStoreItemsResponse>(message, ClassId.GET_SHOP_ITEMS_RESPONSE);
325
333
 
326
334
  }
327
335
 
328
336
  public async missionsGetItems(user_ext_id: string): Promise<GetAchievementMapResponse> {
329
337
 
330
338
  const message = this.buildMessage<GetAchievementMapRequest, GetAchievementMapResponse>(user_ext_id, ClassId.GET_ACHIEVEMENT_MAP_REQUEST);
331
- const response = await this.send<GetAchievementMapResponse>(message);
339
+ const response = await this.send<GetAchievementMapResponse>(message, ClassId.GET_ACHIEVEMENT_MAP_RESPONSE);
332
340
  if (response.achievements) {
333
341
  response.achievements = response.achievements.filter(a => a.ach_type_id === AchievementType.Mission);
334
342
  }
335
343
  return response;
336
344
  }
337
345
 
346
+ public async missionsGetItemsT(user_ext_id?: string): Promise<TMissionOrBadge[]> {
347
+ return UserAchievementTransform((await this.missionsGetItems(user_ext_id)).achievements);
348
+ }
349
+
338
350
  public async badgetsGetItems(user_ext_id: string): Promise<GetAchievementMapResponse> {
339
351
 
340
352
  const message = this.buildMessage<GetAchievementMapRequest, GetAchievementMapResponse>(user_ext_id, ClassId.GET_ACHIEVEMENT_MAP_REQUEST);
341
- const response = await this.send<GetAchievementMapResponse>(message);
353
+ const response = await this.send<GetAchievementMapResponse>(message, ClassId.GET_ACHIEVEMENT_MAP_RESPONSE);
342
354
  if (response.achievements) {
343
355
  response.achievements = response.achievements.filter(a => a.ach_type_id === AchievementType.Badge);
344
356
  }
@@ -348,7 +360,7 @@ class SmarticoAPI {
348
360
  public async tournamentsGetLobby(user_ext_id: string): Promise<GetTournamentsResponse> {
349
361
 
350
362
  const message = this.buildMessage<GetTournamentsRequest, GetTournamentsResponse>(user_ext_id, ClassId.GET_TOURNAMENT_LOBBY_REQUEST);
351
- return await this.send<GetTournamentsResponse>(message);
363
+ return await this.send<GetTournamentsResponse>(message, ClassId.GET_TOURNAMENT_LOBBY_RESPONSE);
352
364
 
353
365
  }
354
366
 
@@ -359,7 +371,7 @@ class SmarticoAPI {
359
371
  tournamentInstanceId
360
372
  }
361
373
  );
362
- const response = await this.send<GetTournamentInfoResponse>(message);
374
+ const response = await this.send<GetTournamentInfoResponse>(message, ClassId.GET_TOURNAMENT_LOBBY_RESPONSE);
363
375
 
364
376
  if (response.userPosition?.avatar_id) {
365
377
  response.userPosition.avatar_url = CoreUtils.avatarUrl(response.userPosition.avatar_id, this.avatarDomain);
@@ -385,9 +397,7 @@ class SmarticoAPI {
385
397
  }
386
398
  );
387
399
 
388
- const response = await this.send<GetLeaderBoardsResponse>(message);
389
-
390
-
400
+ const response = await this.send<GetLeaderBoardsResponse>(message, ClassId.GET_LEADERS_BOARD_RESPONSE);
391
401
 
392
402
  const boardKey = Object.keys(response.map).find( k => period_type_id === undefined || k === period_type_id?.toString());
393
403
 
@@ -410,10 +420,15 @@ class SmarticoAPI {
410
420
 
411
421
  }
412
422
 
413
- public async levelsGet(user_ext_id?: string ): Promise<GetLevelMapResponse> {
423
+ public async levelsGet(user_ext_id?: string): Promise<GetLevelMapResponse> {
414
424
  const message = this.buildMessage<any, GetLevelMapResponse>(user_ext_id, ClassId.GET_LEVEL_MAP_REQUEST);
415
425
  return await this.send<GetLevelMapResponse>(message, ClassId.GET_LEVEL_MAP_RESPONSE);
416
426
  }
427
+
428
+ public async levelsGetT(user_ext_id?: string): Promise<TLevel[]> {
429
+ return GetLevelMapResponseTransform(await this.levelsGet(user_ext_id));
430
+ }
431
+
417
432
 
418
433
  public getWSCalls(): WSAPI {
419
434
  return new WSAPI(this);
@@ -1,18 +1,34 @@
1
+ import { CoreUtils } from "../Core";
1
2
  import { SmarticoAPI } from "../SmarticoAPI";
2
3
 
3
- import { GetLevelMapClearedResponse, levelCleaner } from "./WSAPITypes";
4
+ import { TLevel, TMissionOrBadge, TUserProfile } from "./WSAPITypes";
4
5
 
5
6
  /** @group General API */
6
7
  export class WSAPI {
7
- private static api: SmarticoAPI;
8
-
8
+
9
9
  /** @private */
10
- constructor(api: SmarticoAPI) {
11
- WSAPI.api = api;
10
+ constructor(private api: SmarticoAPI) {
12
11
  }
13
12
 
14
- public async getLevelsTransformed(): Promise<GetLevelMapClearedResponse[]> {
15
- const levels = await WSAPI.api.levelsGet(null);
16
- return levelCleaner(levels);
13
+ /** Returns all the levels available the current user */
14
+ public async getUserProfile(): Promise<TUserProfile> {
15
+ if (this.api.tracker) {
16
+ const o: TUserProfile = Object.assign({}, this.api.tracker.userPublicProps);
17
+ o.avatar_url = CoreUtils.avatarUrl(this.api.tracker.userPublicProps.avatar_id, this.api.avatarDomain);
18
+ return o;
19
+ } else {
20
+ throw new Error('Tracker is not initialized, cannot getUserProfile');
21
+ }
22
+ }
23
+
24
+ /** Returns all the levels available the current user */
25
+ public async getLevels(): Promise<TLevel[]> {
26
+ return this.api.levelsGetT(null);
17
27
  }
28
+
29
+ /** Returns all the missions available the current user */
30
+ public async getMissions(): Promise<TMissionOrBadge[]> {
31
+ return this.api.missionsGetItemsT(null);
32
+ }
33
+
18
34
  }