@smartico/public-api 0.0.380 → 0.0.382
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/CLAUDE.md +103 -0
- package/README.md +32 -10
- package/dist/Base/ClassId.d.ts +2 -0
- package/dist/Jackpots/JackpotDetails.d.ts +14 -15
- package/dist/Jackpots/JackpotPot.d.ts +10 -6
- package/dist/MiniGames/SAWGameType.d.ts +3 -1
- package/dist/MiniGames/SAWTemplateUI.d.ts +7 -0
- package/dist/Raffle/GetRaffleWonPrizesRequest.d.ts +9 -0
- package/dist/Raffle/GetRaffleWonPrizesResponse.d.ts +52 -0
- package/dist/Raffle/index.d.ts +2 -0
- package/dist/SmarticoAPI.d.ts +6 -1
- package/dist/SmarticoLib/index.d.ts +5 -1
- package/dist/WSAPI/WSAPIAvatars.d.ts +267 -49
- package/dist/WSAPI/WSAPIBonuses.d.ts +224 -10
- package/dist/WSAPI/WSAPIGamePick.d.ts +538 -253
- package/dist/WSAPI/WSAPIGeneral.d.ts +156 -14
- package/dist/WSAPI/WSAPIInbox.d.ts +547 -58
- package/dist/WSAPI/WSAPIJackpots.d.ts +292 -57
- package/dist/WSAPI/WSAPILeaderBoard.d.ts +127 -13
- package/dist/WSAPI/WSAPIMiniGames.d.ts +465 -49
- package/dist/WSAPI/WSAPIRaffles.d.ts +576 -52
- package/dist/WSAPI/WSAPITournaments.d.ts +3 -3
- package/dist/WSAPI/WSAPITypes.d.ts +243 -132
- package/dist/WSAPI/WSAPIUser.d.ts +193 -43
- package/dist/index.js +3412 -616
- package/dist/index.js.map +1 -1
- package/dist/index.modern.mjs +3395 -609
- package/dist/index.modern.mjs.map +1 -1
- package/docs/Callbacks.md +162 -0
- package/docs/SmarticoObject.md +445 -0
- package/docs/Transforms.md +99 -0
- package/docs/api/README.md +26 -0
- package/docs/api/classes/WSAPIAvatars.md +282 -54
- package/docs/api/classes/WSAPIBonuses.md +233 -12
- package/docs/api/classes/WSAPIClans.md +380 -10
- package/docs/api/classes/WSAPIGamePick.md +555 -26
- package/docs/api/classes/WSAPIGeneral.md +165 -16
- package/docs/api/classes/WSAPIInbox.md +588 -64
- package/docs/api/classes/WSAPIJackpots.md +320 -66
- package/docs/api/classes/WSAPILeaderBoard.md +133 -15
- package/docs/api/classes/WSAPIMiniGames.md +501 -64
- package/docs/api/classes/WSAPIMissions.md +58 -79
- package/docs/api/classes/WSAPIRaffles.md +647 -69
- package/docs/api/classes/WSAPIStore.md +83 -108
- package/docs/api/classes/WSAPITournaments.md +495 -28
- package/docs/api/classes/WSAPIUser.md +520 -83
- package/docs/api/documents/Callbacks.md +162 -0
- package/docs/api/documents/SmarticoObject.md +445 -0
- package/docs/api/documents/Transforms.md +99 -0
- package/docs/api/enumerations/BonusStatus-1.md +11 -6
- package/docs/api/enumerations/JoinClanErrorCode.md +81 -0
- package/docs/api/enumerations/TournamentRegistrationError.md +12 -0
- package/docs/api/functions/clanTournamentPlayersTransform.md +13 -0
- package/docs/api/interfaces/AvatarCustomized.md +25 -0
- package/docs/api/interfaces/AvatarDefinition.md +94 -0
- package/docs/api/interfaces/AvatarPrompt.md +45 -0
- package/docs/api/interfaces/BonusMetaMap-1.md +4 -1
- package/docs/api/interfaces/BonusTemplateMetaMap-1.md +9 -4
- package/docs/api/interfaces/Clan.md +4 -0
- package/docs/api/interfaces/ClanInfo.md +109 -0
- package/docs/api/interfaces/ClanMember.md +53 -0
- package/docs/api/interfaces/ClanTournamentPlayerRaw.md +67 -0
- package/docs/api/interfaces/GemsDiamondsLog.md +43 -0
- package/docs/api/interfaces/GetClanInfoResponse.md +61 -0
- package/docs/api/interfaces/GetClanTournamentPlayersResponse.md +81 -0
- package/docs/api/interfaces/GetRaffleWonPrizesRequest.md +59 -0
- package/docs/api/interfaces/GetRaffleWonPrizesResponse.md +95 -0
- package/docs/api/interfaces/InboxMarkMessageAction.md +10 -2
- package/docs/api/interfaces/JackpotDetails.md +14 -15
- package/docs/api/interfaces/JackpotPot.md +9 -6
- package/docs/api/interfaces/LeaderBoardDetailsT.md +14 -8
- package/docs/api/interfaces/LeaderBoardUserT.md +8 -5
- package/docs/api/interfaces/LeaderBoardsRewardsT.md +7 -0
- package/docs/api/interfaces/PointsLog.md +43 -0
- package/docs/api/interfaces/RaffleWonPrize.md +59 -0
- package/docs/api/interfaces/RaffleWonPrizePublicMeta.md +27 -0
- package/docs/api/interfaces/RaffleWonPrizeUser.md +43 -0
- package/docs/api/interfaces/TAchCategory.md +2 -7
- package/docs/api/interfaces/TAvatarCustomized.md +4 -4
- package/docs/api/interfaces/TAvatarDefinition.md +13 -14
- package/docs/api/interfaces/TAvatarPrompt.md +6 -6
- package/docs/api/interfaces/TBonus.md +16 -8
- package/docs/api/interfaces/TBuyStoreItemResult.md +4 -29
- package/docs/api/interfaces/TClaimBonusResult.md +5 -5
- package/docs/api/interfaces/TClan.md +8 -4
- package/docs/api/interfaces/TClanInfo.md +47 -0
- package/docs/api/interfaces/TClanJoinResult.md +11 -1
- package/docs/api/interfaces/TClanTournamentPlayer.md +55 -0
- package/docs/api/interfaces/TClanTournamentPlayersResult.md +27 -0
- package/docs/api/interfaces/TClans.md +3 -1
- package/docs/api/interfaces/TGetTranslations.md +4 -0
- package/docs/api/interfaces/TInboxMessage.md +14 -6
- package/docs/api/interfaces/TInboxMessageBody.md +18 -12
- package/docs/api/interfaces/TLevel.md +17 -20
- package/docs/api/interfaces/TLevelCurrent.md +19 -18
- package/docs/api/interfaces/TMiniGamePlayBatchResult.md +14 -6
- package/docs/api/interfaces/TMiniGamePlayResult.md +9 -4
- package/docs/api/interfaces/TMissionClaimRewardResult.md +1 -9
- package/docs/api/interfaces/TMissionOptInResult.md +1 -5
- package/docs/api/interfaces/TMissionOrBadge.md +4 -7
- package/docs/api/interfaces/TRaffleOptinResponse.md +4 -2
- package/docs/api/interfaces/TSegmentCheckResult.md +10 -0
- package/docs/api/interfaces/TSetAvatarResult.md +3 -3
- package/docs/api/interfaces/TStoreItem.md +3 -13
- package/docs/api/interfaces/TTournament.md +1 -1
- package/docs/api/interfaces/TTournamentDetailed.md +1 -1
- package/docs/api/interfaces/TTournamentRegistrationResult.md +4 -2
- package/docs/api/interfaces/TUICustomSection.md +23 -19
- package/docs/api/interfaces/TUserProfile.md +18 -16
- package/docs/api/interfaces/TransformedRaffleClaimPrizeResponse.md +6 -2
- package/docs/api/interfaces/UserLevelExtraCountersT.md +9 -2
- package/docs/api/type-aliases/ActivityLogEntry.md +3 -0
- package/docs/native/ADDING_METHODS.md +7 -2
- package/docs/native/PROTOCOL.md +337 -0
- package/docs/ui/avatars/UIGuide_getAvatarPrompts.md +100 -0
- package/docs/ui/avatars/UIGuide_getAvatarsCustomized.md +90 -0
- package/docs/ui/avatars/UIGuide_getAvatarsList.md +105 -0
- package/docs/ui/avatars/UIGuide_setAvatar.md +118 -0
- package/docs/ui/bonuses/UIGuide_claimBonus.md +144 -0
- package/docs/ui/bonuses/UIGuide_getBonuses.md +176 -0
- package/docs/ui/gamepick/UIGuide_gamePickGetActiveRound.md +99 -0
- package/docs/ui/gamepick/UIGuide_gamePickGetActiveRounds.md +76 -0
- package/docs/ui/gamepick/UIGuide_gamePickGetBoard.md +81 -0
- package/docs/ui/gamepick/UIGuide_gamePickGetGameInfo.md +78 -0
- package/docs/ui/gamepick/UIGuide_gamePickGetHistory.md +55 -0
- package/docs/ui/gamepick/UIGuide_gamePickGetRoundInfoForUser.md +71 -0
- package/docs/ui/gamepick/UIGuide_gamePickGetUserInfo.md +64 -0
- package/docs/ui/gamepick/UIGuide_gamePickSubmitSelection.md +103 -0
- package/docs/ui/gamepick/UIGuide_gamePickSubmitSelectionQuiz.md +67 -0
- package/docs/ui/general/UIGuide_getCustomSections.md +137 -0
- package/docs/ui/general/UIGuide_getRelatedItemsForGame.md +140 -0
- package/docs/ui/inbox/UIGuide_deleteInboxMessage.md +135 -0
- package/docs/ui/inbox/UIGuide_getInboxMessageBody.md +133 -0
- package/docs/ui/inbox/UIGuide_getInboxMessages.md +186 -0
- package/docs/ui/inbox/UIGuide_markInboxMessageAsRead.md +122 -0
- package/docs/ui/inbox/UIGuide_markUnmarkInboxMessageAsFavorite.md +84 -0
- package/docs/ui/jackpots/UIGuide_getJackpotEligibleGames.md +73 -0
- package/docs/ui/jackpots/UIGuide_getJackpotWinners.md +83 -0
- package/docs/ui/jackpots/UIGuide_jackpotGet.md +138 -0
- package/docs/ui/jackpots/UIGuide_jackpotOptIn.md +85 -0
- package/docs/ui/jackpots/UIGuide_jackpotOptOut.md +65 -0
- package/docs/ui/leaderboard/UIGuide_getLeaderBoard.md +166 -0
- package/docs/ui/minigames/UIGuide_getMiniGames.md +153 -0
- package/docs/ui/minigames/UIGuide_getMiniGamesHistory.md +90 -0
- package/docs/ui/minigames/UIGuide_playMiniGame.md +150 -0
- package/docs/ui/minigames/UIGuide_playMiniGameBatch.md +128 -0
- package/docs/ui/raffles/UIGuide_claimRafflePrize.md +99 -0
- package/docs/ui/raffles/UIGuide_getRaffleDrawRun.md +117 -0
- package/docs/ui/raffles/UIGuide_getRaffleDrawRunsHistory.md +92 -0
- package/docs/ui/raffles/UIGuide_getRaffleWonPrizes.md +120 -0
- package/docs/ui/raffles/UIGuide_getRaffles.md +175 -0
- package/docs/ui/raffles/UIGuide_requestRaffleOptin.md +114 -0
- package/docs/ui/user/UIGuide_getActivityLog.md +130 -0
- package/docs/ui/user/UIGuide_getLevels.md +47 -42
- package/package.json +1 -1
- package/src/Base/ClassId.ts +2 -0
- package/src/Jackpots/JackpotDetails.ts +14 -15
- package/src/Jackpots/JackpotPot.ts +10 -6
- package/src/MiniGames/SAWGameType.ts +3 -0
- package/src/MiniGames/SAWTemplateUI.ts +10 -0
- package/src/Raffle/GetRaffleWonPrizesRequest.ts +12 -0
- package/src/Raffle/GetRaffleWonPrizesResponse.ts +56 -0
- package/src/Raffle/index.ts +3 -1
- package/src/SmarticoAPI.ts +14 -1
- package/src/SmarticoLib/index.ts +4 -0
- package/src/WSAPI/WSAPIAvatars.ts +267 -49
- package/src/WSAPI/WSAPIBonuses.ts +224 -10
- package/src/WSAPI/WSAPIGamePick.ts +538 -253
- package/src/WSAPI/WSAPIGeneral.ts +156 -14
- package/src/WSAPI/WSAPIInbox.ts +545 -56
- package/src/WSAPI/WSAPIJackpots.ts +297 -61
- package/src/WSAPI/WSAPILeaderBoard.ts +127 -13
- package/src/WSAPI/WSAPIMiniGames.ts +465 -49
- package/src/WSAPI/WSAPIRaffles.ts +592 -64
- package/src/WSAPI/WSAPITournaments.ts +3 -3
- package/src/WSAPI/WSAPITypes.ts +243 -132
- package/src/WSAPI/WSAPIUser.ts +193 -43
- package/tsconfig.json +9 -1
|
@@ -3,35 +3,158 @@
|
|
|
3
3
|
|
|
4
4
|
### getClans()
|
|
5
5
|
|
|
6
|
-
> **getClans**(`
|
|
6
|
+
> **getClans**(`params?`): `Promise`\<[`TClans`](../interfaces/TClans.md)\>
|
|
7
7
|
|
|
8
|
-
Returns clans
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
Returns the active clans visible to the current user along with the
|
|
9
|
+
user's own membership state (`user_clan_id`, `cooldown_until`,
|
|
10
|
+
`join_date`). Use this to power a clan-picker / clan-browser screen.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
The returned `clans[]` is server-sorted by `rating_position` ASC
|
|
13
|
+
(1 = highest-ranked). The server has already filtered out archived
|
|
14
|
+
clans, clans the user fails segment conditions for, and (when any
|
|
15
|
+
clan has a non-zero score) clans with a zero rating score.
|
|
13
16
|
|
|
14
17
|
#### Parameters
|
|
15
18
|
|
|
16
|
-
#####
|
|
19
|
+
##### params?
|
|
20
|
+
|
|
21
|
+
Optional. Omit to fetch without subscribing.
|
|
17
22
|
|
|
18
23
|
###### onUpdate?
|
|
19
24
|
|
|
20
25
|
(`data`) => `void`
|
|
21
26
|
|
|
27
|
+
Callback invoked with the full refreshed
|
|
28
|
+
`TClans` payload whenever the 30 s cache
|
|
29
|
+
expires and a subsequent fetch lands.
|
|
30
|
+
Each call to `getClans` overwrites the
|
|
31
|
+
prior callback.
|
|
32
|
+
|
|
22
33
|
#### Returns
|
|
23
34
|
|
|
24
35
|
`Promise`\<[`TClans`](../interfaces/TClans.md)\>
|
|
25
36
|
|
|
37
|
+
Promise resolving to `TClans`. Empty
|
|
38
|
+
`clans` array if no clans are visible.
|
|
39
|
+
|
|
40
|
+
#### Remarks
|
|
41
|
+
|
|
42
|
+
**Subscription model (`onUpdate`)**
|
|
43
|
+
The callback receives the FULL refreshed `TClans` payload (never a
|
|
44
|
+
diff/patch). Each subsequent call to `getClans({ onUpdate })`
|
|
45
|
+
REPLACES the prior callback. Pass `onUpdate: undefined` (or omit
|
|
46
|
+
it) to keep the prior callback in place; the callback is never
|
|
47
|
+
auto-cleared.
|
|
48
|
+
|
|
49
|
+
**Update triggers** — note that, unlike most other subscription
|
|
50
|
+
methods in the SDK, this callback is **poll-driven only**. There
|
|
51
|
+
is NO server push that refreshes the clans list. The callback
|
|
52
|
+
fires when:
|
|
53
|
+
|
|
54
|
+
1. The 30-second cache TTL expires and a subsequent `getClans()`
|
|
55
|
+
call (from the consumer) triggers a fresh fetch.
|
|
56
|
+
|
|
57
|
+
Consequence: clan-membership changes (other users joining your
|
|
58
|
+
clan, an operator-driven kick, a clan being archived) surface
|
|
59
|
+
only on the next consumer-driven fetch. If your UI needs
|
|
60
|
+
near-live state, poll `getClans()` on an interval; or re-call
|
|
61
|
+
after a [joinClan](#joinclan) resolves to pick up the new
|
|
62
|
+
`user_clan_id` immediately.
|
|
63
|
+
|
|
64
|
+
**Reading state from the returned payload**
|
|
65
|
+
Drive list rendering from `clans[]` (already sorted). Identify
|
|
66
|
+
the user's own clan via `clan.clan_id === user_clan_id`
|
|
67
|
+
(`null` for clanless users). Detect an active switch-cooldown
|
|
68
|
+
with `cooldown_until !== null` — when set, the user cannot join
|
|
69
|
+
any clan until the cooldown expires, even clans they could
|
|
70
|
+
normally join. The cooldown is **user-level**, not per-clan.
|
|
71
|
+
|
|
72
|
+
`cooldown_until` is an ISO 8601 UTC datetime string with no
|
|
73
|
+
timezone suffix (`"YYYY-MM-DDTHH:MM:SS"`). Parse as UTC:
|
|
74
|
+
`new Date(cooldown_until + 'Z')` or `moment.utc(cooldown_until)`.
|
|
75
|
+
Display in the user's local time. The default cooldown period
|
|
76
|
+
is configured per label by the operator (typically 7 days).
|
|
77
|
+
|
|
78
|
+
`rating_position` is a global rank computed server-side across
|
|
79
|
+
all active clans in the label (1 = highest-rated). Because some
|
|
80
|
+
clans may be hidden by per-user segment visibility, positions
|
|
81
|
+
the user sees may skip (e.g. 1, 3, 7) — don't assume the array
|
|
82
|
+
spans a contiguous range.
|
|
83
|
+
|
|
84
|
+
The `entry_fee_currency_type_id` enum on each clan uses values
|
|
85
|
+
`0` = points, `1` = gems, `2` = diamonds, `3` = free. Compare
|
|
86
|
+
`entry_fee_amount` against the user's matching balance (from
|
|
87
|
+
[getUserProfile](WSAPIUser.md#getuserprofile)) to drive Join button affordability.
|
|
88
|
+
|
|
89
|
+
**Cache TTL**: the SDK caches the response for 30 seconds. Cache
|
|
90
|
+
is fully cleared on login / logout.
|
|
91
|
+
|
|
92
|
+
**Idempotency**: safe. Read-only. Repeated calls within the
|
|
93
|
+
cache window return a deep-cloned cached payload without a
|
|
94
|
+
network round-trip.
|
|
95
|
+
|
|
96
|
+
**Side effects**: none — pure metadata read.
|
|
97
|
+
|
|
98
|
+
**UI guidance**: see [UI Guide — `getClans`](../_media/UIGuide_getClans.md).
|
|
99
|
+
|
|
100
|
+
**Visitor mode**: not supported.
|
|
101
|
+
|
|
102
|
+
#### Example
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
const result = await window._smartico.api.getClans({
|
|
106
|
+
onUpdate: (refreshed) => {
|
|
107
|
+
console.log('[smartico] clans payload refreshed (poll-driven; ~30 s cadence) — re-render the clan list from this payload:', refreshed);
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
console.log('[smartico] user is', result.user_clan_id == null ? 'clanless' : 'in clan ' + result.user_clan_id);
|
|
112
|
+
|
|
113
|
+
// Cooldown handling — affects ALL clans, not a specific one.
|
|
114
|
+
if (result.cooldown_until) {
|
|
115
|
+
const cooldownEndsUtc = new Date(result.cooldown_until + 'Z');
|
|
116
|
+
console.log('[smartico] switch-cooldown active — disable all Join buttons until', cooldownEndsUtc.toLocaleString(),
|
|
117
|
+
'(local). Render the cooldown end on the disabled button label.');
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Render clans — already sorted by rating_position ASC.
|
|
121
|
+
for (const clan of result.clans) {
|
|
122
|
+
const isMine = clan.clan_id === result.user_clan_id;
|
|
123
|
+
const isFull = clan.member_count >= clan.capacity_limit;
|
|
124
|
+
|
|
125
|
+
if (isMine) {
|
|
126
|
+
console.log('[smartico] highlight clan', clan.clan_id, 'as "Your clan"; CTA label "Your clan", no-op');
|
|
127
|
+
} else if (result.cooldown_until) {
|
|
128
|
+
console.log('[smartico] clan', clan.clan_id, '— Join blocked by user cooldown; show disabled button with cooldown end date');
|
|
129
|
+
} else if (isFull) {
|
|
130
|
+
console.log('[smartico] clan', clan.clan_id, '— Clan full; show disabled "Clan is full" button');
|
|
131
|
+
} else {
|
|
132
|
+
const label = clan.entry_fee_amount === 0 || clan.entry_fee_currency_type_id === 3
|
|
133
|
+
? 'Join free'
|
|
134
|
+
: `Join (${clan.entry_fee_amount} ${['Points','Gems','Diamonds'][clan.entry_fee_currency_type_id]})`;
|
|
135
|
+
console.log('[smartico] clan', clan.clan_id, '— render enabled Join button labelled', label);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// After a successful joinClan(), re-call getClans manually — no push refresh.
|
|
140
|
+
// const r = await window._smartico.api.joinClan(targetClanId);
|
|
141
|
+
// if (r.errCode === 0) await window._smartico.api.getClans();
|
|
142
|
+
```
|
|
143
|
+
|
|
26
144
|
***
|
|
27
145
|
|
|
28
146
|
### getClanInfo()
|
|
29
147
|
|
|
30
148
|
> **getClanInfo**(`clanId`): `Promise`\<[`TClanInfo`](../interfaces/TClanInfo.md)\>
|
|
31
149
|
|
|
32
|
-
Returns
|
|
150
|
+
Returns the full detail of a single clan — adds the ranked
|
|
151
|
+
`members[]` roster and a fresh `cooldown_until` on top of the same
|
|
152
|
+
fields exposed on a `TClan` list entry. Use this to power a clan
|
|
153
|
+
detail screen / popup after the user picks an item from
|
|
154
|
+
[getClans](#getclans).
|
|
33
155
|
|
|
34
|
-
|
|
156
|
+
Each call is a fresh server round-trip — there is no client cache
|
|
157
|
+
and no push event refreshes detail state. Re-call to refresh.
|
|
35
158
|
|
|
36
159
|
#### Parameters
|
|
37
160
|
|
|
@@ -39,19 +162,114 @@ Returns detailed information for a specific clan including its members.
|
|
|
39
162
|
|
|
40
163
|
`number`
|
|
41
164
|
|
|
165
|
+
The clan ID from `TClans.clans[i].clan_id`.
|
|
166
|
+
|
|
42
167
|
#### Returns
|
|
43
168
|
|
|
44
169
|
`Promise`\<[`TClanInfo`](../interfaces/TClanInfo.md)\>
|
|
45
170
|
|
|
171
|
+
Promise resolving to `TClanInfo`. Rejects if the
|
|
172
|
+
clan ID is invalid or the user lacks visibility
|
|
173
|
+
for it.
|
|
174
|
+
|
|
175
|
+
#### Remarks
|
|
176
|
+
|
|
177
|
+
**Preconditions**
|
|
178
|
+
Pass a valid `clanId` (typically read from
|
|
179
|
+
`TClans.clans[i].clan_id` returned by [getClans](#getclans)). The
|
|
180
|
+
method works standalone — `getClans()` is not required first —
|
|
181
|
+
but is the only stable source of valid IDs.
|
|
182
|
+
|
|
183
|
+
**Refresh model**
|
|
184
|
+
- **No subscription.** One-shot promise.
|
|
185
|
+
- **No client cache.** Every call sends a network request.
|
|
186
|
+
- **No push event** refreshes the detail. Member-join, kick, or
|
|
187
|
+
contribution-score changes require a fresh `getClanInfo` call.
|
|
188
|
+
|
|
189
|
+
**Returned shape — beyond `TClan`**
|
|
190
|
+
`TClanInfo` adds two things on top of the same identity / capacity
|
|
191
|
+
/ fee / rating fields you'd see on a `TClan` list entry:
|
|
192
|
+
1. A ranked `members[]` array — each entry carries `user_id`,
|
|
193
|
+
`public_username`, `avatar_id` / `avatar_real_id`, the resolved
|
|
194
|
+
`avatar_url`, the member's `position` (rank within this clan),
|
|
195
|
+
`contribution_score`, the `is_me` flag identifying the current
|
|
196
|
+
user's row, and the optional `clean_ext_user_id`. The server
|
|
197
|
+
orders members by score DESC (i.e. `position` ASC); no
|
|
198
|
+
client-side re-sort is required.
|
|
199
|
+
2. A fresh `cooldown_until` on the clan info itself. This is the
|
|
200
|
+
SAME user-level cooldown as `TClans.cooldown_until` (the
|
|
201
|
+
cooldown is global to the user, not per clan) — but `getClans`
|
|
202
|
+
returns a value cached for up to 30 s while `getClanInfo`
|
|
203
|
+
always returns the current value. If the list-cached cooldown
|
|
204
|
+
has just expired, this detail call will reflect it first.
|
|
205
|
+
|
|
206
|
+
**Username display**: in the default Smartico UI, member rows use
|
|
207
|
+
`public_username`. Some surfaces (e.g. the tournament clan
|
|
208
|
+
drill-down) prefer `clean_ext_user_id` as the primary display
|
|
209
|
+
with `public_username` as fallback — pick the convention that
|
|
210
|
+
matches your product's identity model.
|
|
211
|
+
|
|
212
|
+
**Idempotency**: safe. Read-only.
|
|
213
|
+
|
|
214
|
+
**Side effects**: none — pure metadata read.
|
|
215
|
+
|
|
216
|
+
**UI guidance**: see [UI Guide — `getClanInfo`](../_media/UIGuide_getClanInfo.md).
|
|
217
|
+
|
|
218
|
+
**Visitor mode**: not supported.
|
|
219
|
+
|
|
220
|
+
#### Example
|
|
221
|
+
|
|
222
|
+
```ts
|
|
223
|
+
const result = await window._smartico.api.getClans();
|
|
224
|
+
const clan = result.clans[0];
|
|
225
|
+
|
|
226
|
+
console.log('[smartico] loading detail for clan', clan.clan_id);
|
|
227
|
+
const detail = await window._smartico.api.getClanInfo(clan.clan_id);
|
|
228
|
+
|
|
229
|
+
console.log('[smartico] render detail with', detail.members.length, 'members');
|
|
230
|
+
|
|
231
|
+
// Find current user's row to power a sticky "me" footer.
|
|
232
|
+
const meRow = detail.members.find(m => m.is_me);
|
|
233
|
+
if (meRow) {
|
|
234
|
+
console.log('[smartico] current user rank in this clan:', meRow.position,
|
|
235
|
+
'contribution:', meRow.contribution_score, '— render sticky my-member footer');
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Resolve Join CTA state using the detail's cooldown (always fresh).
|
|
239
|
+
const isMyClan = detail.clan_id === result.user_clan_id;
|
|
240
|
+
const inCooldown = detail.cooldown_until != null;
|
|
241
|
+
const isFull = detail.member_count >= detail.capacity_limit;
|
|
242
|
+
if (isMyClan) {
|
|
243
|
+
console.log('[smartico] this is the user\'s clan — render disabled "Your clan" button');
|
|
244
|
+
} else if (inCooldown) {
|
|
245
|
+
const ends = new Date(detail.cooldown_until + 'Z');
|
|
246
|
+
console.log('[smartico] user is in clan-switch cooldown until', ends.toLocaleString(),
|
|
247
|
+
'— render disabled cooldown button');
|
|
248
|
+
} else if (isFull) {
|
|
249
|
+
console.log('[smartico] clan is full — render disabled "Clan is full" button');
|
|
250
|
+
} else {
|
|
251
|
+
console.log('[smartico] joinable — render enabled Join button');
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
46
255
|
***
|
|
47
256
|
|
|
48
257
|
### joinClan()
|
|
49
258
|
|
|
50
259
|
> **joinClan**(`clanId`): `Promise`\<[`TClanJoinResult`](../interfaces/TClanJoinResult.md)\>
|
|
51
260
|
|
|
52
|
-
Joins a clan on behalf of the current user.
|
|
261
|
+
Joins (or switches into) a clan on behalf of the current user. For
|
|
262
|
+
paid clans (`entry_fee_amount > 0`), the user's balance for the
|
|
263
|
+
matching currency is debited synchronously before the response
|
|
264
|
+
returns. If the user is already in a clan, this is treated as an
|
|
265
|
+
atomic clan-switch (deactivate old membership + insert new + debit
|
|
266
|
+
fee, all in one transaction — the user is never observably
|
|
267
|
+
clanless).
|
|
53
268
|
|
|
54
|
-
|
|
269
|
+
A successful response (`errCode === 0`) means: membership is
|
|
270
|
+
persisted, the fee (if any) has been debited, the user's
|
|
271
|
+
switch-cooldown has restarted, and a clan-joined CRM event has
|
|
272
|
+
fired server-side.
|
|
55
273
|
|
|
56
274
|
#### Parameters
|
|
57
275
|
|
|
@@ -59,8 +277,160 @@ Joins a clan on behalf of the current user.
|
|
|
59
277
|
|
|
60
278
|
`number`
|
|
61
279
|
|
|
280
|
+
The clan ID from `TClans.clans[i].clan_id` (or
|
|
281
|
+
`TClanInfo.clan_id`).
|
|
282
|
+
|
|
62
283
|
#### Returns
|
|
63
284
|
|
|
64
285
|
`Promise`\<[`TClanJoinResult`](../interfaces/TClanJoinResult.md)\>
|
|
65
286
|
|
|
287
|
+
`{ errCode, errMsg }`; success when `errCode === 0`.
|
|
288
|
+
Note camelCase keys (see "Result shape note" above).
|
|
289
|
+
|
|
290
|
+
#### Remarks
|
|
291
|
+
|
|
292
|
+
**Result shape note**: `TClanJoinResult` uses `errCode` / `errMsg`
|
|
293
|
+
(camelCase) — different from most other SDK result types in this
|
|
294
|
+
library which use `err_code` / `err_message` (snake_case). Branch
|
|
295
|
+
on the camelCase keys when reading this method's result.
|
|
296
|
+
|
|
297
|
+
**Preconditions**
|
|
298
|
+
Read the candidate from [getClans](#getclans) and gate the call on
|
|
299
|
+
`clan.member_count < clan.capacity_limit`, `cooldown_until == null`
|
|
300
|
+
(on the `TClans` payload — the cooldown is user-level, not
|
|
301
|
+
per-clan), and the user's balance for `entry_fee_currency_type_id`
|
|
302
|
+
being at least `entry_fee_amount` (free clans bypass this check).
|
|
303
|
+
The SDK forwards the call unconditionally — calling without
|
|
304
|
+
satisfying these will most likely return one of the error codes
|
|
305
|
+
below.
|
|
306
|
+
|
|
307
|
+
**Error codes** (in `errCode`, typed as [JoinClanErrorCode](../enumerations/JoinClanErrorCode.md))
|
|
308
|
+
- `0` (`JOIN_CLAN_OK`) — success; membership persisted, fee
|
|
309
|
+
debited, cooldown restarted.
|
|
310
|
+
- `1000` (`JOIN_CLAN_INVALID_PARAMETERS`) — request body missing
|
|
311
|
+
`clan_id`. Should not occur via the SDK; treat as a programming
|
|
312
|
+
error.
|
|
313
|
+
- `1001` (`JOIN_CLAN_NOT_FOUND`) — clan doesn't exist for this
|
|
314
|
+
label, OR the clan is archived / in draft state. The server
|
|
315
|
+
merges "missing" and "archived" into this single code. Refresh
|
|
316
|
+
`getClans()` and remove the entry from the UI.
|
|
317
|
+
- `1002` (`JOIN_CLAN_FULL`) — capacity reached between the list
|
|
318
|
+
fetch and the join click (`member_count >= capacity_limit` at
|
|
319
|
+
the server's atomic check). Refresh the list — the button will
|
|
320
|
+
become "Clan is full".
|
|
321
|
+
- `1003` (`JOIN_CLAN_INSUFFICIENT_FUNDS`) — insufficient balance
|
|
322
|
+
for the clan's entry fee. A single code covers all three
|
|
323
|
+
currencies (points / gems / diamonds); read
|
|
324
|
+
`clan.entry_fee_currency_type_id` to identify which currency
|
|
325
|
+
the user is short on. Show an insufficient-balance UI naming
|
|
326
|
+
the deficit.
|
|
327
|
+
- `1004` (`JOIN_CLAN_SEGMENT_MISMATCH`) — user does not meet the
|
|
328
|
+
clan's entry segment or numeric conditions. There is no
|
|
329
|
+
client-side pre-guard for this — surface a gating message.
|
|
330
|
+
- `1005` (`JOIN_CLAN_USER_IS_NOT_IN_CLAN`) — this method NEVER
|
|
331
|
+
returns `1005`. The code is shared with the tournament
|
|
332
|
+
registration error space and fires only on
|
|
333
|
+
[registerInTournament](WSAPITournaments.md#registerintournament) responses when a clan-based
|
|
334
|
+
tournament requires the user to be in a clan first.
|
|
335
|
+
- `1006` (`JOIN_CLAN_COOLDOWN_ACTIVE`) — user is inside the
|
|
336
|
+
switch-cooldown window from a previous clan join (default
|
|
337
|
+
7 days, configurable per label). Surface the
|
|
338
|
+
`TClans.cooldown_until` expiry in the disabled CTA.
|
|
339
|
+
- `1007` (`JOIN_CLAN_ARCHIVED`) — defined on the public enum but
|
|
340
|
+
the server does NOT emit this code in practice (archived clans
|
|
341
|
+
are reported as `1001`). Handle it as a synonym for `1001`
|
|
342
|
+
defensively, but do not rely on it.
|
|
343
|
+
- `1011` (`JOIN_CLAN_JOINED_AFTER_TOURNAMENT_START`) — this
|
|
344
|
+
method does NOT return `1011` directly. The code fires on
|
|
345
|
+
[registerInTournament](WSAPITournaments.md#registerintournament) responses when the user joined
|
|
346
|
+
their current clan after the tournament started AND already
|
|
347
|
+
has tournament scores.
|
|
348
|
+
- other non-zero — generic server error. Surface `errMsg` if any.
|
|
349
|
+
|
|
350
|
+
**Idempotency**: NOT safe — and notably dangerous. Calling
|
|
351
|
+
`joinClan` with the user's CURRENT `clanId` does NOT short-circuit
|
|
352
|
+
server-side; the call is treated as a clan-switch to the same
|
|
353
|
+
clan. If the label's cooldown is non-zero (the default), the
|
|
354
|
+
second call returns `1006`. If the cooldown is configured to
|
|
355
|
+
zero, the second call will deduct the entry fee AGAIN, deactivate
|
|
356
|
+
the membership, and re-insert it. The SDK does NOT enforce an
|
|
357
|
+
in-flight lock. Consumers MUST guard the call site against
|
|
358
|
+
double-clicks (set a local "joining" flag on click, clear it on
|
|
359
|
+
response) AND short-circuit when the user is already in the
|
|
360
|
+
target clan.
|
|
361
|
+
|
|
362
|
+
**Refresh after success (and after failure)**
|
|
363
|
+
The SDK does NOT automatically refresh the [getClans](#getclans) cache
|
|
364
|
+
after a join. Manually re-call `getClans()` on success to pick up
|
|
365
|
+
the new `user_clan_id`, refreshed `member_count`, and the new
|
|
366
|
+
`cooldown_until` value. Until you do, the cached `TClans` payload
|
|
367
|
+
is stale.
|
|
368
|
+
|
|
369
|
+
**Side effects** (consumer-observable on success)
|
|
370
|
+
- Entry-fee currency balance decreases by `entry_fee_amount`
|
|
371
|
+
(visible on the next [getUserProfile](WSAPIUser.md#getuserprofile) refresh / via the
|
|
372
|
+
user-properties update channel).
|
|
373
|
+
- The user's clan membership row is created (or replaced, on a
|
|
374
|
+
switch). `member_count` on the new clan increments by 1; on a
|
|
375
|
+
switch, the old clan's `member_count` decrements by 1 in the
|
|
376
|
+
same transaction.
|
|
377
|
+
- The user's switch-cooldown restarts at the join time (the
|
|
378
|
+
`TClans.cooldown_until` field on the next list fetch reflects
|
|
379
|
+
the new expiry).
|
|
380
|
+
- Server-side CRM analytics fire (clan-joined event, currency-
|
|
381
|
+
deducted event for paid clans). These surface only as
|
|
382
|
+
server-side traces; the SDK consumer observes them indirectly
|
|
383
|
+
via balance / membership refresh.
|
|
384
|
+
|
|
385
|
+
**UI guidance**: see [UI Guide — `joinClan`](../_media/UIGuide_joinClan.md).
|
|
386
|
+
|
|
387
|
+
**Visitor mode**: not supported. The server rejects the request
|
|
388
|
+
for unauthenticated sessions.
|
|
389
|
+
|
|
390
|
+
#### Example
|
|
391
|
+
|
|
392
|
+
```ts
|
|
393
|
+
const result = await window._smartico.api.getClans();
|
|
394
|
+
const target = result.clans.find(c => c.clan_id === clanId);
|
|
395
|
+
|
|
396
|
+
if (!target) {
|
|
397
|
+
console.log('[smartico] clan not in current list — refresh getClans and retry');
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
if (target.clan_id === result.user_clan_id) {
|
|
401
|
+
console.log('[smartico] user is already in this clan — short-circuit; do NOT call joinClan again, the server will treat it as a switch and may re-deduct the fee');
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
if (result.cooldown_until) {
|
|
405
|
+
console.log('[smartico] user is in cooldown — disable Join until', new Date(result.cooldown_until + 'Z').toLocaleString());
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
if (target.member_count >= target.capacity_limit) {
|
|
409
|
+
console.log('[smartico] clan is full — disable Join');
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
console.log('[smartico] join starting — set in-flight flag, show loading dots on Join button, keep modal open');
|
|
414
|
+
const r = await window._smartico.api.joinClan(target.clan_id);
|
|
415
|
+
console.log('[smartico] join response received — clear in-flight flag');
|
|
416
|
+
|
|
417
|
+
if (r.errCode === 0) {
|
|
418
|
+
console.log('[smartico] joined successfully — refresh getClans to pick up the new user_clan_id, member_count, and cooldown_until');
|
|
419
|
+
await window._smartico.api.getClans();
|
|
420
|
+
} else if (r.errCode === 1002) {
|
|
421
|
+
console.error('[smartico] clan is full — refresh list, hide the Join CTA on the now-full clan');
|
|
422
|
+
} else if (r.errCode === 1003) {
|
|
423
|
+
const currencyLabel = ['points', 'gems', 'diamonds'][target.entry_fee_currency_type_id] ?? 'currency';
|
|
424
|
+
console.error('[smartico] insufficient', currencyLabel, '— need', target.entry_fee_amount);
|
|
425
|
+
} else if (r.errCode === 1004) {
|
|
426
|
+
console.error('[smartico] user does not meet segment / entry conditions — show a gating message');
|
|
427
|
+
} else if (r.errCode === 1006) {
|
|
428
|
+
console.error('[smartico] cooldown active — surface the cooldown_until from getClans:', result.cooldown_until);
|
|
429
|
+
} else if (r.errCode === 1001) {
|
|
430
|
+
console.error('[smartico] clan not found or archived — refresh list and remove from UI');
|
|
431
|
+
} else {
|
|
432
|
+
console.error('[smartico] join failed — show a generic error toast with this message:', r.errMsg);
|
|
433
|
+
}
|
|
434
|
+
```
|
|
435
|
+
|
|
66
436
|
***
|