@notidotbot/noti-api-client 1.9.39 → 1.9.41
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/classes/guildClipForward.d.ts +37 -349
- package/dist/classes/guildClipForward.js +10 -0
- package/dist/classes/guildStatChannels.d.ts +106 -0
- package/dist/classes/guildStatChannels.js +44 -0
- package/dist/other/templates.d.ts +204 -2
- package/dist/other/templates.js +177 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -1,357 +1,45 @@
|
|
|
1
|
-
import { GuildClipForwardCreateSchema, GuildClipForwardZod } from '../other/prisma';
|
|
1
|
+
import { GuildClipForward, GuildClipForwardCreateSchema, GuildClipForwardZod } from '../other/prisma';
|
|
2
2
|
import { CancelOutWebResponses, DeepPartial } from '../types';
|
|
3
3
|
import { WebDataManager } from '../core/manager';
|
|
4
|
+
/** The platforms clip forwarding supports. Caps, addons and rows are all counted per platform. */
|
|
5
|
+
export type ClipForwardPlatform = 'kick' | 'twitch';
|
|
6
|
+
/** One platform's allowance: tier default + purchased addon, and how much of it is used. */
|
|
7
|
+
export type ClipForwardCap = {
|
|
8
|
+
currentTotal: number;
|
|
9
|
+
maxLimit: number;
|
|
10
|
+
};
|
|
11
|
+
export type GuildClipForwardsData = {
|
|
12
|
+
forwards: GuildClipForward[];
|
|
13
|
+
/**
|
|
14
|
+
* PER PLATFORM, because the allowance is. `defaultKickClips` and `defaultTwitchClips` are separate
|
|
15
|
+
* tier numbers with separate addons (`additionalKickClips` / `additionalTwitchClips`), so a single
|
|
16
|
+
* pair would be wrong for whichever platform you were rendering.
|
|
17
|
+
*
|
|
18
|
+
* The server computes this with the same helper the create route enforces with, so a UI that
|
|
19
|
+
* believes there is room will not be refused - render the Add control off `currentTotal < maxLimit`
|
|
20
|
+
* rather than counting `forwards` yourself.
|
|
21
|
+
*/
|
|
22
|
+
limits: Record<ClipForwardPlatform, ClipForwardCap>;
|
|
23
|
+
/** Which tier the allowance came from, so an upsell can name it. */
|
|
24
|
+
premium: {
|
|
25
|
+
tierId: string;
|
|
26
|
+
tierName: string;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
4
29
|
export declare class APIGuildClipForward {
|
|
5
30
|
private web;
|
|
6
31
|
constructor(web: WebDataManager);
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
clipForwardId: string;
|
|
19
|
-
minViews: number | null;
|
|
20
|
-
minDuration: number | null;
|
|
21
|
-
maxPerCycle: number | null;
|
|
22
|
-
allowMature: boolean | null;
|
|
23
|
-
includeOffline: boolean | null;
|
|
24
|
-
whitelistClippers: string[];
|
|
25
|
-
blacklistClippers: string[];
|
|
26
|
-
whitelistCategories: string[];
|
|
27
|
-
blacklistCategories: string[];
|
|
28
|
-
lastClipAt: Date | null;
|
|
29
|
-
lastClipId: string | null;
|
|
30
|
-
} | null;
|
|
31
|
-
webhook: ({
|
|
32
|
-
cfCustomMessage: ({
|
|
33
|
-
clipForward: {
|
|
34
|
-
dbId: string;
|
|
35
|
-
guildId: string;
|
|
36
|
-
platform: import("@prisma/client").$Enums.PlatformEnum;
|
|
37
|
-
channelId: string | null;
|
|
38
|
-
streamerUserName: string;
|
|
39
|
-
usePerStreamerEmbeds: boolean | null;
|
|
40
|
-
showNotifyButton: boolean | null;
|
|
41
|
-
pingRoleId: string | null;
|
|
42
|
-
clipForwardId: string;
|
|
43
|
-
minViews: number | null;
|
|
44
|
-
minDuration: number | null;
|
|
45
|
-
maxPerCycle: number | null;
|
|
46
|
-
allowMature: boolean | null;
|
|
47
|
-
includeOffline: boolean | null;
|
|
48
|
-
whitelistClippers: string[];
|
|
49
|
-
blacklistClippers: string[];
|
|
50
|
-
whitelistCategories: string[];
|
|
51
|
-
blacklistCategories: string[];
|
|
52
|
-
lastClipAt: Date | null;
|
|
53
|
-
lastClipId: string | null;
|
|
54
|
-
} | null;
|
|
55
|
-
embed: ({
|
|
56
|
-
fields: ({
|
|
57
|
-
cfMessageEmbed: {
|
|
58
|
-
dbId: string;
|
|
59
|
-
title: string | null;
|
|
60
|
-
description: string;
|
|
61
|
-
url: string | null;
|
|
62
|
-
color: string | null;
|
|
63
|
-
footer: string | null;
|
|
64
|
-
footerIcon: string | null;
|
|
65
|
-
image: string | null;
|
|
66
|
-
thumbnail: string | null;
|
|
67
|
-
author: string | null;
|
|
68
|
-
authorIcon: string | null;
|
|
69
|
-
cfCustomMessageId: string;
|
|
70
|
-
} | null;
|
|
71
|
-
} & {
|
|
72
|
-
name: string;
|
|
73
|
-
dbId: string;
|
|
74
|
-
value: string | null;
|
|
75
|
-
inline: boolean | null;
|
|
76
|
-
cfMessageEmbedId: string;
|
|
77
|
-
})[];
|
|
78
|
-
} & {
|
|
79
|
-
dbId: string;
|
|
80
|
-
title: string | null;
|
|
81
|
-
description: string;
|
|
82
|
-
url: string | null;
|
|
83
|
-
color: string | null;
|
|
84
|
-
footer: string | null;
|
|
85
|
-
footerIcon: string | null;
|
|
86
|
-
image: string | null;
|
|
87
|
-
thumbnail: string | null;
|
|
88
|
-
author: string | null;
|
|
89
|
-
authorIcon: string | null;
|
|
90
|
-
cfCustomMessageId: string;
|
|
91
|
-
}) | null;
|
|
92
|
-
buttons: {
|
|
93
|
-
dbId: string;
|
|
94
|
-
title: string;
|
|
95
|
-
url: string | null;
|
|
96
|
-
emojiUnicodeOrId: string | null;
|
|
97
|
-
cfCustomMessageId: string;
|
|
98
|
-
}[];
|
|
99
|
-
} & {
|
|
100
|
-
dbId: string;
|
|
101
|
-
type: import("@prisma/client").$Enums.StreamerMessageTypeEnum;
|
|
102
|
-
content: string | null;
|
|
103
|
-
showInviteButton: boolean | null;
|
|
104
|
-
showWatchButton: boolean | null;
|
|
105
|
-
clipForwardId: string;
|
|
106
|
-
}) | null;
|
|
107
|
-
} & {
|
|
108
|
-
dbId: string;
|
|
109
|
-
enabled: boolean | null;
|
|
110
|
-
username: string | null;
|
|
111
|
-
avatarUrl: string | null;
|
|
112
|
-
cfCustomMessageId: string;
|
|
113
|
-
}) | null;
|
|
114
|
-
embed: ({
|
|
115
|
-
fields: ({
|
|
116
|
-
cfMessageEmbed: ({
|
|
117
|
-
cfCustomMessage: ({
|
|
118
|
-
clipForward: {
|
|
119
|
-
dbId: string;
|
|
120
|
-
guildId: string;
|
|
121
|
-
platform: import("@prisma/client").$Enums.PlatformEnum;
|
|
122
|
-
channelId: string | null;
|
|
123
|
-
streamerUserName: string;
|
|
124
|
-
usePerStreamerEmbeds: boolean | null;
|
|
125
|
-
showNotifyButton: boolean | null;
|
|
126
|
-
pingRoleId: string | null;
|
|
127
|
-
clipForwardId: string;
|
|
128
|
-
minViews: number | null;
|
|
129
|
-
minDuration: number | null;
|
|
130
|
-
maxPerCycle: number | null;
|
|
131
|
-
allowMature: boolean | null;
|
|
132
|
-
includeOffline: boolean | null;
|
|
133
|
-
whitelistClippers: string[];
|
|
134
|
-
blacklistClippers: string[];
|
|
135
|
-
whitelistCategories: string[];
|
|
136
|
-
blacklistCategories: string[];
|
|
137
|
-
lastClipAt: Date | null;
|
|
138
|
-
lastClipId: string | null;
|
|
139
|
-
} | null;
|
|
140
|
-
webhook: {
|
|
141
|
-
dbId: string;
|
|
142
|
-
enabled: boolean | null;
|
|
143
|
-
username: string | null;
|
|
144
|
-
avatarUrl: string | null;
|
|
145
|
-
cfCustomMessageId: string;
|
|
146
|
-
} | null;
|
|
147
|
-
buttons: {
|
|
148
|
-
dbId: string;
|
|
149
|
-
title: string;
|
|
150
|
-
url: string | null;
|
|
151
|
-
emojiUnicodeOrId: string | null;
|
|
152
|
-
cfCustomMessageId: string;
|
|
153
|
-
}[];
|
|
154
|
-
} & {
|
|
155
|
-
dbId: string;
|
|
156
|
-
type: import("@prisma/client").$Enums.StreamerMessageTypeEnum;
|
|
157
|
-
content: string | null;
|
|
158
|
-
showInviteButton: boolean | null;
|
|
159
|
-
showWatchButton: boolean | null;
|
|
160
|
-
clipForwardId: string;
|
|
161
|
-
}) | null;
|
|
162
|
-
} & {
|
|
163
|
-
dbId: string;
|
|
164
|
-
title: string | null;
|
|
165
|
-
description: string;
|
|
166
|
-
url: string | null;
|
|
167
|
-
color: string | null;
|
|
168
|
-
footer: string | null;
|
|
169
|
-
footerIcon: string | null;
|
|
170
|
-
image: string | null;
|
|
171
|
-
thumbnail: string | null;
|
|
172
|
-
author: string | null;
|
|
173
|
-
authorIcon: string | null;
|
|
174
|
-
cfCustomMessageId: string;
|
|
175
|
-
}) | null;
|
|
176
|
-
} & {
|
|
177
|
-
name: string;
|
|
178
|
-
dbId: string;
|
|
179
|
-
value: string | null;
|
|
180
|
-
inline: boolean | null;
|
|
181
|
-
cfMessageEmbedId: string;
|
|
182
|
-
})[];
|
|
183
|
-
cfCustomMessage: ({
|
|
184
|
-
clipForward: {
|
|
185
|
-
dbId: string;
|
|
186
|
-
guildId: string;
|
|
187
|
-
platform: import("@prisma/client").$Enums.PlatformEnum;
|
|
188
|
-
channelId: string | null;
|
|
189
|
-
streamerUserName: string;
|
|
190
|
-
usePerStreamerEmbeds: boolean | null;
|
|
191
|
-
showNotifyButton: boolean | null;
|
|
192
|
-
pingRoleId: string | null;
|
|
193
|
-
clipForwardId: string;
|
|
194
|
-
minViews: number | null;
|
|
195
|
-
minDuration: number | null;
|
|
196
|
-
maxPerCycle: number | null;
|
|
197
|
-
allowMature: boolean | null;
|
|
198
|
-
includeOffline: boolean | null;
|
|
199
|
-
whitelistClippers: string[];
|
|
200
|
-
blacklistClippers: string[];
|
|
201
|
-
whitelistCategories: string[];
|
|
202
|
-
blacklistCategories: string[];
|
|
203
|
-
lastClipAt: Date | null;
|
|
204
|
-
lastClipId: string | null;
|
|
205
|
-
} | null;
|
|
206
|
-
webhook: {
|
|
207
|
-
dbId: string;
|
|
208
|
-
enabled: boolean | null;
|
|
209
|
-
username: string | null;
|
|
210
|
-
avatarUrl: string | null;
|
|
211
|
-
cfCustomMessageId: string;
|
|
212
|
-
} | null;
|
|
213
|
-
buttons: {
|
|
214
|
-
dbId: string;
|
|
215
|
-
title: string;
|
|
216
|
-
url: string | null;
|
|
217
|
-
emojiUnicodeOrId: string | null;
|
|
218
|
-
cfCustomMessageId: string;
|
|
219
|
-
}[];
|
|
220
|
-
} & {
|
|
221
|
-
dbId: string;
|
|
222
|
-
type: import("@prisma/client").$Enums.StreamerMessageTypeEnum;
|
|
223
|
-
content: string | null;
|
|
224
|
-
showInviteButton: boolean | null;
|
|
225
|
-
showWatchButton: boolean | null;
|
|
226
|
-
clipForwardId: string;
|
|
227
|
-
}) | null;
|
|
228
|
-
} & {
|
|
229
|
-
dbId: string;
|
|
230
|
-
title: string | null;
|
|
231
|
-
description: string;
|
|
232
|
-
url: string | null;
|
|
233
|
-
color: string | null;
|
|
234
|
-
footer: string | null;
|
|
235
|
-
footerIcon: string | null;
|
|
236
|
-
image: string | null;
|
|
237
|
-
thumbnail: string | null;
|
|
238
|
-
author: string | null;
|
|
239
|
-
authorIcon: string | null;
|
|
240
|
-
cfCustomMessageId: string;
|
|
241
|
-
}) | null;
|
|
242
|
-
buttons: ({
|
|
243
|
-
cfCustomMessage: ({
|
|
244
|
-
clipForward: {
|
|
245
|
-
dbId: string;
|
|
246
|
-
guildId: string;
|
|
247
|
-
platform: import("@prisma/client").$Enums.PlatformEnum;
|
|
248
|
-
channelId: string | null;
|
|
249
|
-
streamerUserName: string;
|
|
250
|
-
usePerStreamerEmbeds: boolean | null;
|
|
251
|
-
showNotifyButton: boolean | null;
|
|
252
|
-
pingRoleId: string | null;
|
|
253
|
-
clipForwardId: string;
|
|
254
|
-
minViews: number | null;
|
|
255
|
-
minDuration: number | null;
|
|
256
|
-
maxPerCycle: number | null;
|
|
257
|
-
allowMature: boolean | null;
|
|
258
|
-
includeOffline: boolean | null;
|
|
259
|
-
whitelistClippers: string[];
|
|
260
|
-
blacklistClippers: string[];
|
|
261
|
-
whitelistCategories: string[];
|
|
262
|
-
blacklistCategories: string[];
|
|
263
|
-
lastClipAt: Date | null;
|
|
264
|
-
lastClipId: string | null;
|
|
265
|
-
} | null;
|
|
266
|
-
webhook: {
|
|
267
|
-
dbId: string;
|
|
268
|
-
enabled: boolean | null;
|
|
269
|
-
username: string | null;
|
|
270
|
-
avatarUrl: string | null;
|
|
271
|
-
cfCustomMessageId: string;
|
|
272
|
-
} | null;
|
|
273
|
-
embed: ({
|
|
274
|
-
fields: ({
|
|
275
|
-
cfMessageEmbed: {
|
|
276
|
-
dbId: string;
|
|
277
|
-
title: string | null;
|
|
278
|
-
description: string;
|
|
279
|
-
url: string | null;
|
|
280
|
-
color: string | null;
|
|
281
|
-
footer: string | null;
|
|
282
|
-
footerIcon: string | null;
|
|
283
|
-
image: string | null;
|
|
284
|
-
thumbnail: string | null;
|
|
285
|
-
author: string | null;
|
|
286
|
-
authorIcon: string | null;
|
|
287
|
-
cfCustomMessageId: string;
|
|
288
|
-
} | null;
|
|
289
|
-
} & {
|
|
290
|
-
name: string;
|
|
291
|
-
dbId: string;
|
|
292
|
-
value: string | null;
|
|
293
|
-
inline: boolean | null;
|
|
294
|
-
cfMessageEmbedId: string;
|
|
295
|
-
})[];
|
|
296
|
-
} & {
|
|
297
|
-
dbId: string;
|
|
298
|
-
title: string | null;
|
|
299
|
-
description: string;
|
|
300
|
-
url: string | null;
|
|
301
|
-
color: string | null;
|
|
302
|
-
footer: string | null;
|
|
303
|
-
footerIcon: string | null;
|
|
304
|
-
image: string | null;
|
|
305
|
-
thumbnail: string | null;
|
|
306
|
-
author: string | null;
|
|
307
|
-
authorIcon: string | null;
|
|
308
|
-
cfCustomMessageId: string;
|
|
309
|
-
}) | null;
|
|
310
|
-
} & {
|
|
311
|
-
dbId: string;
|
|
312
|
-
type: import("@prisma/client").$Enums.StreamerMessageTypeEnum;
|
|
313
|
-
content: string | null;
|
|
314
|
-
showInviteButton: boolean | null;
|
|
315
|
-
showWatchButton: boolean | null;
|
|
316
|
-
clipForwardId: string;
|
|
317
|
-
}) | null;
|
|
318
|
-
} & {
|
|
319
|
-
dbId: string;
|
|
320
|
-
title: string;
|
|
321
|
-
url: string | null;
|
|
322
|
-
emojiUnicodeOrId: string | null;
|
|
323
|
-
cfCustomMessageId: string;
|
|
324
|
-
})[];
|
|
325
|
-
} & {
|
|
326
|
-
dbId: string;
|
|
327
|
-
type: import("@prisma/client").$Enums.StreamerMessageTypeEnum;
|
|
328
|
-
content: string | null;
|
|
329
|
-
showInviteButton: boolean | null;
|
|
330
|
-
showWatchButton: boolean | null;
|
|
331
|
-
clipForwardId: string;
|
|
332
|
-
})[];
|
|
333
|
-
} & {
|
|
334
|
-
dbId: string;
|
|
335
|
-
guildId: string;
|
|
336
|
-
platform: import("@prisma/client").$Enums.PlatformEnum;
|
|
337
|
-
channelId: string | null;
|
|
338
|
-
streamerUserName: string;
|
|
339
|
-
usePerStreamerEmbeds: boolean | null;
|
|
340
|
-
showNotifyButton: boolean | null;
|
|
341
|
-
pingRoleId: string | null;
|
|
342
|
-
clipForwardId: string;
|
|
343
|
-
minViews: number | null;
|
|
344
|
-
minDuration: number | null;
|
|
345
|
-
maxPerCycle: number | null;
|
|
346
|
-
allowMature: boolean | null;
|
|
347
|
-
includeOffline: boolean | null;
|
|
348
|
-
whitelistClippers: string[];
|
|
349
|
-
blacklistClippers: string[];
|
|
350
|
-
whitelistCategories: string[];
|
|
351
|
-
blacklistCategories: string[];
|
|
352
|
-
lastClipAt: Date | null;
|
|
353
|
-
lastClipId: string | null;
|
|
354
|
-
})[]>>;
|
|
32
|
+
/**
|
|
33
|
+
* Every clip-forward rule for this guild, with the per-platform allowance.
|
|
34
|
+
*
|
|
35
|
+
* **BREAKING in 1.9.40**: this returned `GuildClipForward[]` directly. The rows moved to
|
|
36
|
+
* `data.forwards` so the allowance could travel with them - `WebResponse` is exactly
|
|
37
|
+
* `{ status, data }`, so there is no room for a sibling field and an array has nowhere to put one.
|
|
38
|
+
*
|
|
39
|
+
* The caps were always enforced on create; they were simply never reported, which made a capped
|
|
40
|
+
* feature indistinguishable from an uncapped one until the create failed.
|
|
41
|
+
*/
|
|
42
|
+
getGuildClipForwards({ auth, guildId }: GuildClipForwardFunctionsInput['getGuildClipForwards']): Promise<import("../types").WebResponse<GuildClipForwardsData>>;
|
|
355
43
|
getGuildClipForward({ auth, guildId, clipForwardId }: GuildClipForwardFunctionsInput['getGuildClipForward']): Promise<import("../types").WebResponse<{
|
|
356
44
|
customMessages: ({
|
|
357
45
|
clipForward: {
|
|
@@ -8,6 +8,16 @@ class APIGuildClipForward {
|
|
|
8
8
|
this.web = web;
|
|
9
9
|
}
|
|
10
10
|
// Methods.
|
|
11
|
+
/**
|
|
12
|
+
* Every clip-forward rule for this guild, with the per-platform allowance.
|
|
13
|
+
*
|
|
14
|
+
* **BREAKING in 1.9.40**: this returned `GuildClipForward[]` directly. The rows moved to
|
|
15
|
+
* `data.forwards` so the allowance could travel with them - `WebResponse` is exactly
|
|
16
|
+
* `{ status, data }`, so there is no room for a sibling field and an array has nowhere to put one.
|
|
17
|
+
*
|
|
18
|
+
* The caps were always enforced on create; they were simply never reported, which made a capped
|
|
19
|
+
* feature indistinguishable from an uncapped one until the create failed.
|
|
20
|
+
*/
|
|
11
21
|
async getGuildClipForwards({ auth, guildId }) {
|
|
12
22
|
return await this.web.request({
|
|
13
23
|
method: 'GET', auth,
|
|
@@ -10,6 +10,33 @@ import { WebDataManager } from '../core/manager';
|
|
|
10
10
|
export type StatChannelPlatform = 'kick' | 'twitch' | 'youtube' | 'tiktok' | 'rumble' | 'whatnot' | 'twitter';
|
|
11
11
|
/** Only Kick has a follower counter. Every other model has `isLive` alone. */
|
|
12
12
|
export type StatChannelKind = 'isLive' | 'followers';
|
|
13
|
+
/**
|
|
14
|
+
* What `createStatChannels` accepts, which is NOT `StatChannelKind`.
|
|
15
|
+
*
|
|
16
|
+
* `liveUpdates` is the same counter `StatChannelKind` calls `isLive`. The create body has said
|
|
17
|
+
* `liveUpdates` since counters were made from `POST /panel`, and the rest of the stat-channel surface
|
|
18
|
+
* says `isLive`; the server keeps both rather than breaking existing callers, and its RESPONSE always
|
|
19
|
+
* speaks `StatChannelKind`. So you send `liveUpdates` and read `isLive` back, deliberately.
|
|
20
|
+
*/
|
|
21
|
+
export type StatChannelCreateType = 'liveUpdates' | 'followers';
|
|
22
|
+
/**
|
|
23
|
+
* The three counter names a guild can format.
|
|
24
|
+
*
|
|
25
|
+
* NOT `StatChannelKind` - that is which CHANNEL exists (`isLive` is one channel whose name changes
|
|
26
|
+
* between states), while `live` and `offline` are two templates for that same channel.
|
|
27
|
+
*/
|
|
28
|
+
export type StatChannelFormatKind = 'live' | 'offline' | 'followers';
|
|
29
|
+
/**
|
|
30
|
+
* Per-platform counter name formats.
|
|
31
|
+
*
|
|
32
|
+
* A counter's name came from ONE guild-wide template, so a server watching Kick and Twitch got the
|
|
33
|
+
* identical name for both. An entry here overrides that for one platform; a platform with no entry
|
|
34
|
+
* falls back to the guild-wide template, which falls back to the bot's default.
|
|
35
|
+
*
|
|
36
|
+
* `followers` is Kick-only - it is the only platform with a follower counter at all, and the API
|
|
37
|
+
* refuses the key elsewhere rather than storing something no channel could use.
|
|
38
|
+
*/
|
|
39
|
+
export type StatChannelFormats = Partial<Record<StatChannelPlatform, Partial<Record<StatChannelFormatKind, string>>>>;
|
|
13
40
|
/**
|
|
14
41
|
* Why a counter is or is not updating.
|
|
15
42
|
*
|
|
@@ -50,6 +77,24 @@ export type StatChannelsData = {
|
|
|
50
77
|
* `cluster-unreachable` and none of them says anything about the channels themselves.
|
|
51
78
|
*/
|
|
52
79
|
inspected: boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Platforms a counter can be CREATED for, which is narrower than the platforms that can hold one.
|
|
82
|
+
*
|
|
83
|
+
* Creating a counter needs the bot to resolve the creator's live state first, and only some
|
|
84
|
+
* platforms have a check for that - so YouTube, X and Whatnot can carry a counter that already
|
|
85
|
+
* exists while refusing a new one. Read this instead of hard-coding the list: it is served from the
|
|
86
|
+
* single constant the server also gates the create route on, and it widened once already.
|
|
87
|
+
*
|
|
88
|
+
* Absent on an API older than 1.9.40, so treat `undefined` as "Kick only".
|
|
89
|
+
*/
|
|
90
|
+
canCreate?: StatChannelPlatform[];
|
|
91
|
+
/**
|
|
92
|
+
* The per-platform name formats currently stored, so an editor can render them without a second
|
|
93
|
+
* call. `{}` when nothing is overridden - never null.
|
|
94
|
+
*
|
|
95
|
+
* Absent on an API older than 1.9.41.
|
|
96
|
+
*/
|
|
97
|
+
formats?: StatChannelFormats;
|
|
53
98
|
channels: StatChannel[];
|
|
54
99
|
};
|
|
55
100
|
export type UpdatedStatChannel = {
|
|
@@ -71,6 +116,17 @@ export type DeletedStatChannels = {
|
|
|
71
116
|
/** Always false. Unlinking stops the counter; the Discord channel stays theirs to remove. */
|
|
72
117
|
channelDeleted: boolean;
|
|
73
118
|
};
|
|
119
|
+
export type CreatedStatChannels = {
|
|
120
|
+
platform: StatChannelPlatform;
|
|
121
|
+
username: string;
|
|
122
|
+
/**
|
|
123
|
+
* One entry per counter created, in `updateStatChannel`'s shape.
|
|
124
|
+
*
|
|
125
|
+
* Read back from the database after creation rather than echoing the request, so the ids are the
|
|
126
|
+
* ones that actually landed. A caller does not need to re-`getStatChannels` to learn them.
|
|
127
|
+
*/
|
|
128
|
+
channels: UpdatedStatChannel[];
|
|
129
|
+
};
|
|
74
130
|
export type RetriedStatChannel = {
|
|
75
131
|
platform: StatChannelPlatform;
|
|
76
132
|
username: string;
|
|
@@ -87,6 +143,40 @@ export declare class APIGuildStatChannels {
|
|
|
87
143
|
constructor(web: WebDataManager);
|
|
88
144
|
/** Every counter this guild has configured, with why each is or is not updating. */
|
|
89
145
|
getStatChannels({ auth, guildId }: GuildStatChannelsFunctionsInput['getStatChannels']): Promise<WebResponse<StatChannelsData>>;
|
|
146
|
+
/**
|
|
147
|
+
* Set the per-platform counter name formats.
|
|
148
|
+
*
|
|
149
|
+
* **REPLACES the whole map** - send it in full every time. Omit a platform to drop its override,
|
|
150
|
+
* send `{}` to clear every one. It does NOT merge, and that is deliberate: under merge a key once
|
|
151
|
+
* written could never be removed and the unset state would be unreachable after the first save.
|
|
152
|
+
* Same contract as fishing's `logChannelOverrides`.
|
|
153
|
+
*
|
|
154
|
+
* Requires the message-editor feature as well as stat counters - 403 without it, because storing a
|
|
155
|
+
* format that would never be read looks saved and does nothing.
|
|
156
|
+
*
|
|
157
|
+
* 400 on a platform that cannot have counters, on a `followers` format for anything but Kick, and
|
|
158
|
+
* on a format over 100 characters - refused rather than truncated, since a silently shortened
|
|
159
|
+
* channel name is not what anyone typed.
|
|
160
|
+
*/
|
|
161
|
+
updateStatChannelFormats({ auth, guildId, formats }: GuildStatChannelsFunctionsInput['updateStatChannelFormats']): Promise<WebResponse<{
|
|
162
|
+
formats: StatChannelFormats;
|
|
163
|
+
}>>;
|
|
164
|
+
/**
|
|
165
|
+
* Create the counter channels themselves, and link them.
|
|
166
|
+
*
|
|
167
|
+
* Use this rather than making a voice channel and pointing `updateStatChannel` at it - the bot
|
|
168
|
+
* names the new channel from the server's own `statChannelLive` / `statFollowers` template and sets
|
|
169
|
+
* its permissions.
|
|
170
|
+
*
|
|
171
|
+
* **Check `canCreate` from `getStatChannels` first.** Creating needs the bot to read the creator's
|
|
172
|
+
* live state, and the platforms that support that are narrower than the ones that can hold a
|
|
173
|
+
* counter - a platform outside that list is a 400, not a silent no-op.
|
|
174
|
+
*
|
|
175
|
+
* `followers` is Kick-only; asking for it anywhere else is a 400 naming the platform. 404 when the
|
|
176
|
+
* creator is not tracked in this guild, 400 when the live or follower read failed, in which case
|
|
177
|
+
* nothing was created.
|
|
178
|
+
*/
|
|
179
|
+
createStatChannels({ auth, guildId, platform, username, types }: GuildStatChannelsFunctionsInput['createStatChannels']): Promise<WebResponse<CreatedStatChannels>>;
|
|
90
180
|
/**
|
|
91
181
|
* Point a counter at a channel, creating it if the creator had none.
|
|
92
182
|
*
|
|
@@ -114,6 +204,18 @@ export type GuildStatChannelsFunctionsInput = {
|
|
|
114
204
|
auth: string;
|
|
115
205
|
guildId: string;
|
|
116
206
|
};
|
|
207
|
+
'createStatChannels': {
|
|
208
|
+
auth: string;
|
|
209
|
+
guildId: string;
|
|
210
|
+
platform: StatChannelPlatform;
|
|
211
|
+
username: string;
|
|
212
|
+
types: StatChannelCreateType[];
|
|
213
|
+
};
|
|
214
|
+
'updateStatChannelFormats': {
|
|
215
|
+
auth: string;
|
|
216
|
+
guildId: string;
|
|
217
|
+
formats: StatChannelFormats;
|
|
218
|
+
};
|
|
117
219
|
'updateStatChannel': {
|
|
118
220
|
auth: string;
|
|
119
221
|
guildId: string;
|
|
@@ -140,6 +242,10 @@ export type GuildStatChannelsFunctionsInput = {
|
|
|
140
242
|
export type GuildStatChannelsReturnTypes = {
|
|
141
243
|
'getStatChannelsRaw': Awaited<ReturnType<APIGuildStatChannels['getStatChannels']>>;
|
|
142
244
|
'getStatChannelsSuccess': CancelOutWebResponses<Awaited<ReturnType<APIGuildStatChannels['getStatChannels']>>>;
|
|
245
|
+
'createStatChannelsRaw': Awaited<ReturnType<APIGuildStatChannels['createStatChannels']>>;
|
|
246
|
+
'createStatChannelsSuccess': CancelOutWebResponses<Awaited<ReturnType<APIGuildStatChannels['createStatChannels']>>>;
|
|
247
|
+
'updateStatChannelFormatsRaw': Awaited<ReturnType<APIGuildStatChannels['updateStatChannelFormats']>>;
|
|
248
|
+
'updateStatChannelFormatsSuccess': CancelOutWebResponses<Awaited<ReturnType<APIGuildStatChannels['updateStatChannelFormats']>>>;
|
|
143
249
|
'updateStatChannelRaw': Awaited<ReturnType<APIGuildStatChannels['updateStatChannel']>>;
|
|
144
250
|
'updateStatChannelSuccess': CancelOutWebResponses<Awaited<ReturnType<APIGuildStatChannels['updateStatChannel']>>>;
|
|
145
251
|
'deleteStatChannelsRaw': Awaited<ReturnType<APIGuildStatChannels['deleteStatChannels']>>;
|
|
@@ -15,6 +15,50 @@ class APIGuildStatChannels {
|
|
|
15
15
|
endpoint: this.web.qp(`/data/guild/${guildId}/stat-channels`),
|
|
16
16
|
});
|
|
17
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* Set the per-platform counter name formats.
|
|
20
|
+
*
|
|
21
|
+
* **REPLACES the whole map** - send it in full every time. Omit a platform to drop its override,
|
|
22
|
+
* send `{}` to clear every one. It does NOT merge, and that is deliberate: under merge a key once
|
|
23
|
+
* written could never be removed and the unset state would be unreachable after the first save.
|
|
24
|
+
* Same contract as fishing's `logChannelOverrides`.
|
|
25
|
+
*
|
|
26
|
+
* Requires the message-editor feature as well as stat counters - 403 without it, because storing a
|
|
27
|
+
* format that would never be read looks saved and does nothing.
|
|
28
|
+
*
|
|
29
|
+
* 400 on a platform that cannot have counters, on a `followers` format for anything but Kick, and
|
|
30
|
+
* on a format over 100 characters - refused rather than truncated, since a silently shortened
|
|
31
|
+
* channel name is not what anyone typed.
|
|
32
|
+
*/
|
|
33
|
+
async updateStatChannelFormats({ auth, guildId, formats }) {
|
|
34
|
+
return await this.web.request({
|
|
35
|
+
method: 'PATCH', auth,
|
|
36
|
+
endpoint: this.web.qp(`/data/guild/${guildId}/stat-channels/formats`),
|
|
37
|
+
body: { formats },
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Create the counter channels themselves, and link them.
|
|
42
|
+
*
|
|
43
|
+
* Use this rather than making a voice channel and pointing `updateStatChannel` at it - the bot
|
|
44
|
+
* names the new channel from the server's own `statChannelLive` / `statFollowers` template and sets
|
|
45
|
+
* its permissions.
|
|
46
|
+
*
|
|
47
|
+
* **Check `canCreate` from `getStatChannels` first.** Creating needs the bot to read the creator's
|
|
48
|
+
* live state, and the platforms that support that are narrower than the ones that can hold a
|
|
49
|
+
* counter - a platform outside that list is a 400, not a silent no-op.
|
|
50
|
+
*
|
|
51
|
+
* `followers` is Kick-only; asking for it anywhere else is a 400 naming the platform. 404 when the
|
|
52
|
+
* creator is not tracked in this guild, 400 when the live or follower read failed, in which case
|
|
53
|
+
* nothing was created.
|
|
54
|
+
*/
|
|
55
|
+
async createStatChannels({ auth, guildId, platform, username, types }) {
|
|
56
|
+
return await this.web.request({
|
|
57
|
+
method: 'POST', auth,
|
|
58
|
+
endpoint: this.web.qp(`/data/guild/${guildId}/stat-channels/${platform}/${username}`),
|
|
59
|
+
body: { types },
|
|
60
|
+
});
|
|
61
|
+
}
|
|
18
62
|
/**
|
|
19
63
|
* Point a counter at a channel, creating it if the creator had none.
|
|
20
64
|
*
|