@notidotbot/noti-api-client 1.9.73 → 1.9.75

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.
Files changed (59) hide show
  1. package/dist/classes/@me.d.ts +45 -0
  2. package/dist/classes/@me.js +25 -0
  3. package/dist/classes/guildInGame.d.ts +259 -0
  4. package/dist/classes/guildInGame.js +114 -0
  5. package/dist/classes/guildInfluencerPanel.d.ts +13 -0
  6. package/dist/classes/guildMessageScheduler.d.ts +15 -1
  7. package/dist/classes/publicGiveaways.d.ts +1 -1
  8. package/dist/classes/publicGiveaways.js +1 -1
  9. package/dist/core/manager.d.ts +2 -0
  10. package/dist/core/manager.js +2 -0
  11. package/dist/index.d.ts +6 -0
  12. package/dist/index.js +19 -1
  13. package/dist/other/bitfields.d.ts +8 -2
  14. package/dist/other/bitfields.js +6 -0
  15. package/dist/other/features.d.ts +1 -1
  16. package/dist/other/features.js +2 -0
  17. package/dist/other/inGameAlerts.d.ts +83 -0
  18. package/dist/other/inGameAlerts.js +65 -0
  19. package/dist/other/inGameMiniMessage.d.ts +14 -0
  20. package/dist/other/inGameMiniMessage.js +135 -0
  21. package/dist/other/multiDestination.d.ts +89 -0
  22. package/dist/other/multiDestination.js +109 -0
  23. package/dist/other/types.d.ts +2 -0
  24. package/dist/other/zod/clubStreamer.zod.d.ts +12 -0
  25. package/dist/other/zod/clubStreamer.zod.js +10 -0
  26. package/dist/other/zod/giveaways.zod.d.ts +17 -0
  27. package/dist/other/zod/giveaways.zod.js +8 -0
  28. package/dist/other/zod/kickStreamer.zod.d.ts +23 -0
  29. package/dist/other/zod/kickStreamer.zod.js +11 -0
  30. package/dist/other/zod/rumbleStreamer.zod.d.ts +25 -0
  31. package/dist/other/zod/rumbleStreamer.zod.js +11 -0
  32. package/dist/other/zod/scheduledMessage.zod.d.ts +10 -2
  33. package/dist/other/zod/scheduledMessage.zod.js +29 -5
  34. package/dist/other/zod/schema.zod.d.ts +6 -0
  35. package/dist/other/zod/schema.zod.js +7 -1
  36. package/dist/other/zod/tiktokStreamer.zod.d.ts +25 -0
  37. package/dist/other/zod/tiktokStreamer.zod.js +11 -0
  38. package/dist/other/zod/twitchStreamer.zod.d.ts +23 -0
  39. package/dist/other/zod/twitchStreamer.zod.js +11 -0
  40. package/dist/other/zod/twitterStreamer.zod.d.ts +25 -0
  41. package/dist/other/zod/twitterStreamer.zod.js +11 -0
  42. package/dist/other/zod/youtubeStreamer.zod.d.ts +26 -0
  43. package/dist/other/zod/youtubeStreamer.zod.js +11 -0
  44. package/dist/other/zod/zod.d.ts +15 -0
  45. package/dist/other/zod/zod.js +12 -0
  46. package/dist/tsconfig.tsbuildinfo +1 -1
  47. package/package.json +1 -1
  48. package/prisma/generated/ts-prisma.d.ts +129 -0
  49. package/prisma/schema/models/clubStreamer.prisma +9 -0
  50. package/prisma/schema/models/giveaways.prisma +9 -0
  51. package/prisma/schema/models/inGame.prisma +77 -0
  52. package/prisma/schema/models/kickStreamer.prisma +11 -0
  53. package/prisma/schema/models/rumbleStreamer.prisma +12 -0
  54. package/prisma/schema/models/scheduledMessage.prisma +10 -1
  55. package/prisma/schema/models/tiktokStreamer.prisma +11 -0
  56. package/prisma/schema/models/twitchStreamer.prisma +12 -0
  57. package/prisma/schema/models/twitterStreamer.prisma +12 -0
  58. package/prisma/schema/models/youtubeStreamer.prisma +11 -0
  59. package/prisma/schema/schema.prisma +16 -0
@@ -12,6 +12,18 @@ export declare class APIMe {
12
12
  getConnectPlatformUrl({ platform }: MeFunctionsInput['getConnectPlatformUrl']): Promise<import("../types").WebResponse<string>>;
13
13
  connectPlatform({ auth, platform, code, state }: MeFunctionsInput['connectPlatform']): Promise<import("../types").WebResponse<string>>;
14
14
  unlinkPlatform({ auth, platform }: MeFunctionsInput['unlinkPlatform']): Promise<import("../types").WebResponse<string>>;
15
+ /**
16
+ * Link a Minecraft account: the code `/noti link` printed in a connected Minecraft server. The link counts only
17
+ * in that server's Discord server. 400 for a wrong or expired code (it is spent either way), 409 when that
18
+ * Minecraft account is already linked to someone else there. Linking again in the same server replaces the old one.
19
+ */
20
+ connectMinecraft({ auth, code }: MeFunctionsInput['connectMinecraft']): Promise<import("../types").WebResponse<MinecraftLinkResult>>;
21
+ /** Every server this user has linked a Minecraft account in, newest first. */
22
+ getMinecraftLinks({ auth }: MeFunctionsInput['getMinecraftLinks']): Promise<import("../types").WebResponse<{
23
+ links: MinecraftLink[];
24
+ }>>;
25
+ /** Unlink in one server. 404 when nothing is linked there. */
26
+ unlinkMinecraft({ auth, guildId }: MeFunctionsInput['unlinkMinecraft']): Promise<import("../types").WebResponse<string>>;
15
27
  /**
16
28
  * The one server upgrade that comes with User Premium: where it currently sits, and whether it can
17
29
  * be moved yet. Everything the dashboard needs is inside `data` - a field beside it would exist at
@@ -62,6 +74,17 @@ export type MeFunctionsInput<T extends GuildDataType = never> = {
62
74
  'deleteServerPremium': {
63
75
  auth: string;
64
76
  };
77
+ 'connectMinecraft': {
78
+ auth: string;
79
+ code: string;
80
+ };
81
+ 'getMinecraftLinks': {
82
+ auth: string;
83
+ };
84
+ 'unlinkMinecraft': {
85
+ auth: string;
86
+ guildId: string;
87
+ };
65
88
  };
66
89
  export type MeGetReturnTypes = {
67
90
  'getCurrentUserRaw': Awaited<ReturnType<APIMe['getCurrentUser']>>;
@@ -84,6 +107,28 @@ export type MeGetReturnTypes = {
84
107
  'setServerPremiumSuccess': CancelOutWebResponses<Awaited<ReturnType<APIMe['setServerPremium']>>>;
85
108
  'deleteServerPremiumRaw': Awaited<ReturnType<APIMe['deleteServerPremium']>>;
86
109
  'deleteServerPremiumSuccess': CancelOutWebResponses<Awaited<ReturnType<APIMe['deleteServerPremium']>>>;
110
+ 'connectMinecraftRaw': Awaited<ReturnType<APIMe['connectMinecraft']>>;
111
+ 'connectMinecraftSuccess': CancelOutWebResponses<Awaited<ReturnType<APIMe['connectMinecraft']>>>;
112
+ 'getMinecraftLinksRaw': Awaited<ReturnType<APIMe['getMinecraftLinks']>>;
113
+ 'getMinecraftLinksSuccess': CancelOutWebResponses<Awaited<ReturnType<APIMe['getMinecraftLinks']>>>;
114
+ 'unlinkMinecraftRaw': Awaited<ReturnType<APIMe['unlinkMinecraft']>>;
115
+ 'unlinkMinecraftSuccess': CancelOutWebResponses<Awaited<ReturnType<APIMe['unlinkMinecraft']>>>;
116
+ };
117
+ /** What `connectMinecraft` linked. `bedrock`: a Bedrock player through Geyser/Floodgate. */
118
+ export type MinecraftLinkResult = {
119
+ guildId: string;
120
+ uuid: string;
121
+ name: string;
122
+ bedrock: boolean;
123
+ };
124
+ /** One Minecraft account linked in one Discord server. `guildName` is null when Noti is no longer in that server. */
125
+ export type MinecraftLink = {
126
+ guildId: string;
127
+ guildName: string | null;
128
+ uuid: string;
129
+ name: string;
130
+ bedrock: boolean;
131
+ linkedAt: string;
87
132
  };
88
133
  export type DCUserData = {
89
134
  id: string;
@@ -55,6 +55,31 @@ class APIMe {
55
55
  endpoint: this.web.qp('/@me/connect/' + platform),
56
56
  });
57
57
  }
58
+ /**
59
+ * Link a Minecraft account: the code `/noti link` printed in a connected Minecraft server. The link counts only
60
+ * in that server's Discord server. 400 for a wrong or expired code (it is spent either way), 409 when that
61
+ * Minecraft account is already linked to someone else there. Linking again in the same server replaces the old one.
62
+ */
63
+ async connectMinecraft({ auth, code }) {
64
+ return await this.web.request({
65
+ method: 'POST', auth, body: { code },
66
+ endpoint: this.web.qp('/@me/connect/minecraft'),
67
+ });
68
+ }
69
+ /** Every server this user has linked a Minecraft account in, newest first. */
70
+ async getMinecraftLinks({ auth }) {
71
+ return await this.web.request({
72
+ method: 'GET', auth,
73
+ endpoint: this.web.qp('/@me/connect/minecraft'),
74
+ });
75
+ }
76
+ /** Unlink in one server. 404 when nothing is linked there. */
77
+ async unlinkMinecraft({ auth, guildId }) {
78
+ return await this.web.request({
79
+ method: 'DELETE', auth,
80
+ endpoint: this.web.qp('/@me/connect/minecraft/' + guildId),
81
+ });
82
+ }
58
83
  /**
59
84
  * The one server upgrade that comes with User Premium: where it currently sits, and whether it can
60
85
  * be moved yet. Everything the dashboard needs is inside `data` - a field beside it would exist at
@@ -0,0 +1,259 @@
1
+ import { WebDataManager } from '../core/manager';
2
+ import { CancelOutWebResponses, WebResponse } from '../types';
3
+ import type { InGameAlertType, InGamePlatform } from '../other/inGameAlerts';
4
+ /**
5
+ * Minecraft - game servers connected to a Discord server (Noti-v3 phases/in-game/).
6
+ *
7
+ * A server running the Noti plugin with no token prints a code (`K7P-2QX`) to its console. The owner enters it
8
+ * here (`createInGameServer`), which connects that server to this Discord server and returns its token ONCE; the
9
+ * plugin receives it automatically while it is waiting (`delivered: true`); otherwise the dashboard shows it once
10
+ * ("paste into plugins/Noti/token.txt").
11
+ *
12
+ * The plan sets how many servers stay ACTIVE (`limits.servers`: free 1, Premium 3, Premium Plus 10). A network that
13
+ * shares one token counts once. Over the limit (after a downgrade) the rest are kept but paused: pinned servers
14
+ * first, then the oldest, stay active - `active` on each server says which. An upgrade brings them back.
15
+ *
16
+ * Behind the `inGame` launch flag: every method answers 403 until it is beta/public for the caller.
17
+ */
18
+ export declare class APIGuildInGame {
19
+ private web;
20
+ constructor(web: WebDataManager);
21
+ /** Every connected server, oldest first, which are active, and what the plan allows. */
22
+ getInGameServers({ auth, guildId }: InGameFunctionsInput['getInGameServers']): Promise<WebResponse<InGameServersData>>;
23
+ /**
24
+ * Redeem the code a server printed. Case, spaces and the dash do not matter. Returns the new server and its
25
+ * `token`, which is never shown again. 400 when the code is wrong, expired or already used ("Run /noti connect
26
+ * for a new one"); 403 with `{ message, limit, current }` inside `error` when the plan cannot connect another.
27
+ */
28
+ createInGameServer({ auth, guildId, code }: InGameFunctionsInput['createInGameServer']): Promise<WebResponse<InGameServerCreatedData>>;
29
+ /**
30
+ * Rename a server, or pin it so it stays active ahead of older ones when the server is over its plan limit.
31
+ * Send either or both. Returns the whole list again (pinning can change which others are active). 404 when it
32
+ * is not this Discord server's.
33
+ */
34
+ updateInGameServer({ auth, guildId, serverId, ...body }: InGameFunctionsInput['updateInGameServer']): Promise<WebResponse<InGameServersData>>;
35
+ /** Replace the server's token; the old one stops working at once. The new `token` is returned ONCE. */
36
+ rotateInGameServerToken({ auth, guildId, serverId }: InGameFunctionsInput['rotateInGameServerToken']): Promise<WebResponse<InGameTokenData>>;
37
+ /**
38
+ * "Send a test alert": a sample event through the real connection, shown to the server's admins in-game. 409 when
39
+ * the server is not connected right now; 403 with the vote-gate error when the caller must vote first; 429 with
40
+ * `retryAfterSeconds` inside `error` when tests are sent too quickly (count down from it).
41
+ */
42
+ sendInGameServerTest({ auth, guildId, serverId }: InGameFunctionsInput['sendInGameServerTest']): Promise<WebResponse<InGameTestData>>;
43
+ /**
44
+ * Every creator, for the "Choose what shows in Minecraft" picker: whether it has a Discord channel (a creator with
45
+ * none can never show in Minecraft - say so next to it), what shows today, and the types its platform has.
46
+ */
47
+ getInGameCreators({ auth, guildId }: InGameFunctionsInput['getInGameCreators']): Promise<WebResponse<InGameCreatorsData>>;
48
+ /**
49
+ * Save the picker in one call. Each entry changes only the fields it sends; unknown types and picks are dropped.
50
+ * Max 500 entries. The per-creator settings page can also send `inGame` / `inGameTypes` / `inGameServerIds` on the
51
+ * normal creator save. Returns the list again.
52
+ */
53
+ updateInGameCreators({ auth, guildId, creators }: InGameFunctionsInput['updateInGameCreators']): Promise<WebResponse<InGameCreatorsUpdatedData>>;
54
+ /**
55
+ * Minecraft giveaway prizes (in-game P7): one row per winner who linked a Minecraft account, and where it stands -
56
+ * `pending` (waiting for the winner to be online on the paying server), `claimed` (a node is running it), `done`,
57
+ * or `failed` (with the plugin's reason, e.g. an unknown preset). `giveawayId` narrows it to one giveaway.
58
+ * `paused`: the server lost InGameRewards, so stored presets are kept but nothing new is paid.
59
+ */
60
+ getInGameRewards({ auth, guildId, giveawayId }: InGameFunctionsInput['getInGameRewards']): Promise<WebResponse<InGameRewardsData>>;
61
+ /** Disconnect a server. To move it to another Discord server, disconnect it and run /noti connect again. */
62
+ deleteInGameServer({ auth, guildId, serverId }: InGameFunctionsInput['deleteInGameServer']): Promise<WebResponse<InGameServersData>>;
63
+ }
64
+ /** Games a server can connect from. Only Minecraft today; Roblox is planned. */
65
+ export type InGameGame = 'minecraft' | 'roblox';
66
+ export type InGameServer = {
67
+ id: string;
68
+ game: InGameGame;
69
+ /** The server's MOTD at connect time (colour codes stripped), or the name it was renamed to. */
70
+ name: string;
71
+ /** The start of the server's token, so an owner can tell which token a server holds. */
72
+ tokenPrefix: string;
73
+ /** Discord user id of whoever connected it. */
74
+ connectedBy: string;
75
+ /** Kept active ahead of older servers when over the plan limit. */
76
+ pinned: boolean;
77
+ /** False when the Discord server is over its plan limit and this one is paused. */
78
+ active: boolean;
79
+ /** ISO time the server was last connected, or null if it never has been. */
80
+ lastSeenAt: string | null;
81
+ createdAt: string;
82
+ /** Connected right now (at least one node). Live, not stored. */
83
+ connected: boolean;
84
+ /** Every node connected right now: a single server, or each backend and proxy of a network sharing the token. */
85
+ nodes: InGameNode[];
86
+ /** The reward presets its rewards.yml offers, as last reported - the giveaway form's dropdown (P7). */
87
+ rewardPresets: string[];
88
+ };
89
+ export type InGameNode = {
90
+ /** Stable per installation; a network's backends each have their own. */
91
+ instanceId: string;
92
+ /** "Paper", "Spigot", "Velocity", "BungeeCord", ... */
93
+ software: string | null;
94
+ /** Null on a proxy. */
95
+ mcVersion: string | null;
96
+ pluginVersion: string | null;
97
+ players: number | null;
98
+ /** False means offline mode: account linking will be unavailable (P6). Null when unknown. */
99
+ onlineMode: boolean | null;
100
+ /** A BungeeCord / Velocity proxy. */
101
+ proxy: boolean;
102
+ connectedAt: string;
103
+ /**
104
+ * Players can link accounts through this node: online mode, or behind a proxy that forwards checked identities.
105
+ * Use this, not `onlineMode`, for "account linking unavailable": an offline-mode backend behind such a proxy is
106
+ * normal and links fine.
107
+ */
108
+ accountLinking: boolean;
109
+ };
110
+ export type InGameServersLimits = {
111
+ /** Servers the plan keeps active. */
112
+ servers: number;
113
+ /** Servers connected now, active or paused. */
114
+ current: number;
115
+ /** Whether giveaway reward commands are available (`InGameRewards`, Premium). */
116
+ rewards: boolean;
117
+ };
118
+ export type InGameServersData = {
119
+ servers: InGameServer[];
120
+ limits: InGameServersLimits;
121
+ };
122
+ export type InGameServerCreatedData = {
123
+ server: InGameServer;
124
+ /** Shown once. The plugin stores it in plugins/Noti/token.txt. */
125
+ token: string;
126
+ /**
127
+ * True when the waiting server received the token itself - nothing to show. False when it stopped waiting (it
128
+ * restarted, or the code was typed after it shut down): show `token` once, with "paste into plugins/Noti/token.txt".
129
+ */
130
+ delivered: boolean;
131
+ };
132
+ export type InGameTestData = {
133
+ sent: true;
134
+ nodes: number;
135
+ };
136
+ export type InGameCreator = {
137
+ platform: InGamePlatform;
138
+ username: string;
139
+ /** False: no Discord channel set, so it cannot show in Minecraft (Minecraft mirrors Discord). */
140
+ hasChannel: boolean;
141
+ inGame: boolean;
142
+ /** Empty = every type in `availableTypes`. */
143
+ inGameTypes: InGameAlertType[];
144
+ /** Empty = every active server. */
145
+ inGameServerIds: string[];
146
+ /** The types this creator's platform has. */
147
+ availableTypes: InGameAlertType[];
148
+ };
149
+ export type InGameCreatorsData = {
150
+ creators: InGameCreator[];
151
+ };
152
+ /**
153
+ * `updated`: rows changed. `hiddenByMember`: creators NOT turned on because their member hid them from Minecraft in
154
+ * the Influencer Panel - show "Hidden by the member" next to them; only they can change it.
155
+ */
156
+ export type InGameCreatorsUpdatedData = InGameCreatorsData & {
157
+ updated: number;
158
+ hiddenByMember: {
159
+ platform: string;
160
+ username: string;
161
+ }[];
162
+ };
163
+ export type InGameCreatorUpdate = {
164
+ platform: InGamePlatform;
165
+ username: string;
166
+ inGame?: boolean;
167
+ inGameTypes?: InGameAlertType[];
168
+ inGameServerIds?: string[];
169
+ };
170
+ export type InGameTokenData = {
171
+ token: string;
172
+ tokenPrefix: string;
173
+ };
174
+ export type InGameFunctionsInput = {
175
+ 'getInGameServers': {
176
+ auth: string;
177
+ guildId: string;
178
+ };
179
+ 'createInGameServer': {
180
+ auth: string;
181
+ guildId: string;
182
+ code: string;
183
+ };
184
+ 'updateInGameServer': {
185
+ auth: string;
186
+ guildId: string;
187
+ serverId: string;
188
+ name?: string;
189
+ pinned?: boolean;
190
+ };
191
+ 'rotateInGameServerToken': {
192
+ auth: string;
193
+ guildId: string;
194
+ serverId: string;
195
+ };
196
+ 'sendInGameServerTest': {
197
+ auth: string;
198
+ guildId: string;
199
+ serverId: string;
200
+ };
201
+ 'getInGameCreators': {
202
+ auth: string;
203
+ guildId: string;
204
+ };
205
+ 'updateInGameCreators': {
206
+ auth: string;
207
+ guildId: string;
208
+ creators: InGameCreatorUpdate[];
209
+ };
210
+ 'deleteInGameServer': {
211
+ auth: string;
212
+ guildId: string;
213
+ serverId: string;
214
+ };
215
+ 'getInGameRewards': {
216
+ auth: string;
217
+ guildId: string;
218
+ giveawayId?: string;
219
+ };
220
+ };
221
+ export type InGameGetReturnTypes = {
222
+ 'getInGameServersRaw': Awaited<ReturnType<APIGuildInGame['getInGameServers']>>;
223
+ 'getInGameServersSuccess': CancelOutWebResponses<Awaited<ReturnType<APIGuildInGame['getInGameServers']>>>;
224
+ 'createInGameServerRaw': Awaited<ReturnType<APIGuildInGame['createInGameServer']>>;
225
+ 'createInGameServerSuccess': CancelOutWebResponses<Awaited<ReturnType<APIGuildInGame['createInGameServer']>>>;
226
+ 'updateInGameServerRaw': Awaited<ReturnType<APIGuildInGame['updateInGameServer']>>;
227
+ 'updateInGameServerSuccess': CancelOutWebResponses<Awaited<ReturnType<APIGuildInGame['updateInGameServer']>>>;
228
+ 'rotateInGameServerTokenRaw': Awaited<ReturnType<APIGuildInGame['rotateInGameServerToken']>>;
229
+ 'rotateInGameServerTokenSuccess': CancelOutWebResponses<Awaited<ReturnType<APIGuildInGame['rotateInGameServerToken']>>>;
230
+ 'getInGameCreatorsRaw': Awaited<ReturnType<APIGuildInGame['getInGameCreators']>>;
231
+ 'getInGameCreatorsSuccess': CancelOutWebResponses<Awaited<ReturnType<APIGuildInGame['getInGameCreators']>>>;
232
+ 'updateInGameCreatorsRaw': Awaited<ReturnType<APIGuildInGame['updateInGameCreators']>>;
233
+ 'updateInGameCreatorsSuccess': CancelOutWebResponses<Awaited<ReturnType<APIGuildInGame['updateInGameCreators']>>>;
234
+ 'sendInGameServerTestRaw': Awaited<ReturnType<APIGuildInGame['sendInGameServerTest']>>;
235
+ 'sendInGameServerTestSuccess': CancelOutWebResponses<Awaited<ReturnType<APIGuildInGame['sendInGameServerTest']>>>;
236
+ 'deleteInGameServerRaw': Awaited<ReturnType<APIGuildInGame['deleteInGameServer']>>;
237
+ 'deleteInGameServerSuccess': CancelOutWebResponses<Awaited<ReturnType<APIGuildInGame['deleteInGameServer']>>>;
238
+ 'getInGameRewardsRaw': Awaited<ReturnType<APIGuildInGame['getInGameRewards']>>;
239
+ 'getInGameRewardsSuccess': CancelOutWebResponses<Awaited<ReturnType<APIGuildInGame['getInGameRewards']>>>;
240
+ };
241
+ export type InGameRewardStatus = 'pending' | 'claimed' | 'done' | 'failed';
242
+ /** One giveaway prize paid in Minecraft. `uuid` is the winner's linked Minecraft account; `preset` its rewards.yml name. */
243
+ export type InGameReward = {
244
+ rewardId: string;
245
+ giveawayId: string;
246
+ userId: string;
247
+ uuid: string;
248
+ preset: string;
249
+ serverId: string;
250
+ status: InGameRewardStatus;
251
+ /** Why it failed, from the plugin; null otherwise. */
252
+ error: string | null;
253
+ createdAt: string;
254
+ doneAt: string | null;
255
+ };
256
+ export type InGameRewardsData = {
257
+ rewards: InGameReward[];
258
+ paused: boolean;
259
+ };
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.APIGuildInGame = void 0;
4
+ /**
5
+ * Minecraft - game servers connected to a Discord server (Noti-v3 phases/in-game/).
6
+ *
7
+ * A server running the Noti plugin with no token prints a code (`K7P-2QX`) to its console. The owner enters it
8
+ * here (`createInGameServer`), which connects that server to this Discord server and returns its token ONCE; the
9
+ * plugin receives it automatically while it is waiting (`delivered: true`); otherwise the dashboard shows it once
10
+ * ("paste into plugins/Noti/token.txt").
11
+ *
12
+ * The plan sets how many servers stay ACTIVE (`limits.servers`: free 1, Premium 3, Premium Plus 10). A network that
13
+ * shares one token counts once. Over the limit (after a downgrade) the rest are kept but paused: pinned servers
14
+ * first, then the oldest, stay active - `active` on each server says which. An upgrade brings them back.
15
+ *
16
+ * Behind the `inGame` launch flag: every method answers 403 until it is beta/public for the caller.
17
+ */
18
+ class APIGuildInGame {
19
+ web;
20
+ constructor(web) {
21
+ this.web = web;
22
+ }
23
+ /** Every connected server, oldest first, which are active, and what the plan allows. */
24
+ async getInGameServers({ auth, guildId }) {
25
+ return await this.web.request({
26
+ method: 'GET', auth,
27
+ endpoint: this.web.qp(`/data/guild/${guildId}/in-game/servers`),
28
+ });
29
+ }
30
+ /**
31
+ * Redeem the code a server printed. Case, spaces and the dash do not matter. Returns the new server and its
32
+ * `token`, which is never shown again. 400 when the code is wrong, expired or already used ("Run /noti connect
33
+ * for a new one"); 403 with `{ message, limit, current }` inside `error` when the plan cannot connect another.
34
+ */
35
+ async createInGameServer({ auth, guildId, code }) {
36
+ return await this.web.request({
37
+ method: 'POST', auth,
38
+ endpoint: this.web.qp(`/data/guild/${guildId}/in-game/servers`),
39
+ body: { code },
40
+ });
41
+ }
42
+ /**
43
+ * Rename a server, or pin it so it stays active ahead of older ones when the server is over its plan limit.
44
+ * Send either or both. Returns the whole list again (pinning can change which others are active). 404 when it
45
+ * is not this Discord server's.
46
+ */
47
+ async updateInGameServer({ auth, guildId, serverId, ...body }) {
48
+ return await this.web.request({
49
+ method: 'PATCH', auth,
50
+ endpoint: this.web.qp(`/data/guild/${guildId}/in-game/servers/${serverId}`),
51
+ body,
52
+ });
53
+ }
54
+ /** Replace the server's token; the old one stops working at once. The new `token` is returned ONCE. */
55
+ async rotateInGameServerToken({ auth, guildId, serverId }) {
56
+ return await this.web.request({
57
+ method: 'POST', auth,
58
+ endpoint: this.web.qp(`/data/guild/${guildId}/in-game/servers/${serverId}/token`),
59
+ });
60
+ }
61
+ /**
62
+ * "Send a test alert": a sample event through the real connection, shown to the server's admins in-game. 409 when
63
+ * the server is not connected right now; 403 with the vote-gate error when the caller must vote first; 429 with
64
+ * `retryAfterSeconds` inside `error` when tests are sent too quickly (count down from it).
65
+ */
66
+ async sendInGameServerTest({ auth, guildId, serverId }) {
67
+ return await this.web.request({
68
+ method: 'POST', auth,
69
+ endpoint: this.web.qp(`/data/guild/${guildId}/in-game/servers/${serverId}/test`),
70
+ });
71
+ }
72
+ /**
73
+ * Every creator, for the "Choose what shows in Minecraft" picker: whether it has a Discord channel (a creator with
74
+ * none can never show in Minecraft - say so next to it), what shows today, and the types its platform has.
75
+ */
76
+ async getInGameCreators({ auth, guildId }) {
77
+ return await this.web.request({
78
+ method: 'GET', auth,
79
+ endpoint: this.web.qp(`/data/guild/${guildId}/in-game/creators`),
80
+ });
81
+ }
82
+ /**
83
+ * Save the picker in one call. Each entry changes only the fields it sends; unknown types and picks are dropped.
84
+ * Max 500 entries. The per-creator settings page can also send `inGame` / `inGameTypes` / `inGameServerIds` on the
85
+ * normal creator save. Returns the list again.
86
+ */
87
+ async updateInGameCreators({ auth, guildId, creators }) {
88
+ return await this.web.request({
89
+ method: 'PATCH', auth,
90
+ endpoint: this.web.qp(`/data/guild/${guildId}/in-game/creators`),
91
+ body: { creators },
92
+ });
93
+ }
94
+ /**
95
+ * Minecraft giveaway prizes (in-game P7): one row per winner who linked a Minecraft account, and where it stands -
96
+ * `pending` (waiting for the winner to be online on the paying server), `claimed` (a node is running it), `done`,
97
+ * or `failed` (with the plugin's reason, e.g. an unknown preset). `giveawayId` narrows it to one giveaway.
98
+ * `paused`: the server lost InGameRewards, so stored presets are kept but nothing new is paid.
99
+ */
100
+ async getInGameRewards({ auth, guildId, giveawayId }) {
101
+ return await this.web.request({
102
+ method: 'GET', auth,
103
+ endpoint: this.web.qp(`/data/guild/${guildId}/in-game/rewards`, { giveawayId }),
104
+ });
105
+ }
106
+ /** Disconnect a server. To move it to another Discord server, disconnect it and run /noti connect again. */
107
+ async deleteInGameServer({ auth, guildId, serverId }) {
108
+ return await this.web.request({
109
+ method: 'DELETE', auth,
110
+ endpoint: this.web.qp(`/data/guild/${guildId}/in-game/servers/${serverId}`),
111
+ });
112
+ }
113
+ }
114
+ exports.APIGuildInGame = APIGuildInGame;
@@ -87,6 +87,14 @@ export type GuildInfluencerPlatformSettings = {
87
87
  secondaryChannelId: string | null;
88
88
  /** The ping role for videos (YouTube, TikTok, Rumble) or posts (X). Null pings no one on those. */
89
89
  secondaryPingRoleId: string | null;
90
+ /**
91
+ * Minecraft (1.9.75): members' creators on this platform show on the server's connected Minecraft servers. Needs
92
+ * the `inGame` launch flag to turn on (403). Leave it out of a save to keep it as it is. Members can still hide
93
+ * their own from the panel's "My socials" in Discord.
94
+ */
95
+ inGame?: boolean;
96
+ /** Which kinds show (`IN_GAME_TYPES[platform]`); empty = every kind the platform has. */
97
+ inGameTypes?: string[];
90
98
  };
91
99
  /**
92
100
  * The panel message's look. `title` and `description` on every plan; the rest is Premium Plus.
@@ -287,6 +295,11 @@ export type GuildInfluencerEntry = {
287
295
  decidedByUsername?: string | null;
288
296
  /** Rumble only: 'channel' or 'user'. */
289
297
  rumbleType: string | null;
298
+ /**
299
+ * The member hid this creator from Minecraft (1.9.75). Only they can show it again: turning Minecraft on for it
300
+ * from the creator settings answers 409, and the bulk picker skips it (`hiddenByMember`).
301
+ */
302
+ inGameOptOut?: boolean;
290
303
  createdAt: string;
291
304
  updatedAt: string;
292
305
  };
@@ -99,8 +99,18 @@ export type ScheduledButtonInput = {
99
99
  emojiUnicodeOrId?: string | null;
100
100
  };
101
101
  export type ScheduledMessageCreateBody = {
102
- channelId: string;
102
+ /** Required while `sendToDiscord` is on (the default). Omit or null for a Minecraft-only message. */
103
+ channelId?: string | null;
103
104
  content: string;
105
+ /** Default true. At least one of `sendToDiscord` / `sendToInGame` must be on. */
106
+ sendToDiscord?: boolean;
107
+ /** Default false. Needs the `inGame` launch flag (403 otherwise); goes to every connected Minecraft server. */
108
+ sendToInGame?: boolean;
109
+ /**
110
+ * Restricted MiniMessage for Minecraft (`forbiddenMiniMessageTag` says what is refused). Blank or null = the
111
+ * Discord content converted. Placeholders as in `content`; a Minecraft-only message has no {channelName}.
112
+ */
113
+ minecraftContent?: string | null;
104
114
  embed?: ScheduledEmbedInput | null;
105
115
  buttons?: ScheduledButtonInput[];
106
116
  trigger?: ScheduledMessageTrigger;
@@ -118,6 +128,10 @@ export type ScheduledMessageCreateBody = {
118
128
  };
119
129
  export type ScheduledMessageEditBody = {
120
130
  content?: string;
131
+ /** Turning it off is refused (400) when the message does not also go to Discord. Needs the `inGame` flag. */
132
+ sendToInGame?: boolean;
133
+ /** null clears it: the Discord content is converted again. */
134
+ minecraftContent?: string | null;
121
135
  embed?: ScheduledEmbedInput | null;
122
136
  buttons?: ScheduledButtonInput[];
123
137
  webhookEnabled?: boolean;
@@ -75,7 +75,7 @@ export type PublicGiveawaysGetReturnTypes = {
75
75
  * Every reason an entry can be refused. Mirrors `PUBLIC_ENTRY_REFUSALS` in Noti-v3's
76
76
  * `src/modules/publicGiveaways.ts`; the eligibility ones match the card's `requirements` / `entryFilter`.
77
77
  */
78
- export declare const PUBLIC_ENTRY_REFUSALS: readonly ["not_listed", "ended", "full", "not_member", "already_entered", "rate_limited", "role_whitelist", "role_blacklist", "joined_server_before", "account_created_before", "min_account_age", "boosting_server", "roles", "message_count"];
78
+ export declare const PUBLIC_ENTRY_REFUSALS: readonly ["not_listed", "ended", "full", "not_member", "already_entered", "rate_limited", "role_whitelist", "role_blacklist", "joined_server_before", "account_created_before", "min_account_age", "boosting_server", "roles", "message_count", "minecraft_not_linked"];
79
79
  export type PublicEntryRefusal = typeof PUBLIC_ENTRY_REFUSALS[number];
80
80
  export type PublicGiveawayRole = {
81
81
  id: string;
@@ -76,5 +76,5 @@ exports.APIPublicGiveaways = APIPublicGiveaways;
76
76
  exports.PUBLIC_ENTRY_REFUSALS = [
77
77
  'not_listed', 'ended', 'full', 'not_member', 'already_entered', 'rate_limited',
78
78
  'role_whitelist', 'role_blacklist', 'joined_server_before', 'account_created_before', 'min_account_age',
79
- 'boosting_server', 'roles', 'message_count',
79
+ 'boosting_server', 'roles', 'message_count', 'minecraft_not_linked',
80
80
  ];
@@ -10,6 +10,7 @@ import { APIGuildStatChannels } from '../classes/guildStatChannels';
10
10
  import { APIGuildClipForward } from '../classes/guildClipForward';
11
11
  import { APIGuildDrops } from '../classes/guildDrops';
12
12
  import { APIGuildBadges } from '../classes/guildBadges';
13
+ import { APIGuildInGame } from '../classes/guildInGame';
13
14
  import { APIGuildBounties } from '../classes/guildBounties';
14
15
  import { APIGuildAssistant } from '../classes/guildAssistant';
15
16
  import { APIGuildAutoRoles } from '../classes/guildAutoRoles';
@@ -75,6 +76,7 @@ export declare class WebDataManager {
75
76
  readonly telemetry: APITelemetry;
76
77
  readonly guildDrops: APIGuildDrops;
77
78
  readonly guildBadges: APIGuildBadges;
79
+ readonly guildInGame: APIGuildInGame;
78
80
  readonly guildBounties: APIGuildBounties;
79
81
  readonly guildAssistant: APIGuildAssistant;
80
82
  readonly guildAutoRoles: APIGuildAutoRoles;
@@ -16,6 +16,7 @@ const guildStatChannels_1 = require("../classes/guildStatChannels");
16
16
  const guildClipForward_1 = require("../classes/guildClipForward");
17
17
  const guildDrops_1 = require("../classes/guildDrops");
18
18
  const guildBadges_1 = require("../classes/guildBadges");
19
+ const guildInGame_1 = require("../classes/guildInGame");
19
20
  const guildBounties_1 = require("../classes/guildBounties");
20
21
  const guildAssistant_1 = require("../classes/guildAssistant");
21
22
  const guildAutoRoles_1 = require("../classes/guildAutoRoles");
@@ -79,6 +80,7 @@ class WebDataManager {
79
80
  telemetry = new telemetry_1.APITelemetry(this);
80
81
  guildDrops = new guildDrops_1.APIGuildDrops(this);
81
82
  guildBadges = new guildBadges_1.APIGuildBadges(this);
83
+ guildInGame = new guildInGame_1.APIGuildInGame(this);
82
84
  guildBounties = new guildBounties_1.APIGuildBounties(this);
83
85
  guildAssistant = new guildAssistant_1.APIGuildAssistant(this);
84
86
  guildAutoRoles = new guildAutoRoles_1.APIGuildAutoRoles(this);
package/dist/index.d.ts CHANGED
@@ -27,6 +27,7 @@ export * from './classes/telemetry';
27
27
  export * from './classes/vods';
28
28
  export * from './classes/guildDrops';
29
29
  export * from './classes/guildBadges';
30
+ export * from './classes/guildInGame';
30
31
  export * from './classes/guildBounties';
31
32
  export * from './classes/guildAssistant';
32
33
  export * from './classes/guildAutoRoles';
@@ -47,6 +48,11 @@ export { GuildMessageTypeEnum, StreamerMessageTypeEnum, PlatformEnum, $Enums } f
47
48
  export { FEATURE_NAMES, } from './other/features';
48
49
  export { OFFLINE_GRACE_CHOICES, OFFLINE_GRACE_DEFAULT, OFFLINE_GRACE_PLATFORMS, } from './other/offlineGrace';
49
50
  export type { OfflineGraceMinutes, OfflineGracePlatform } from './other/offlineGrace';
51
+ export { DESTINATION_TYPES, MAX_EXTRA_DESTINATIONS, normalizeExtraDestinations, extrasFor, readExtraPosts, hasLivePost, } from './other/multiDestination';
52
+ export type { DestinationPlatform, DestinationType, ExtraDestination, ExtraPost } from './other/multiDestination';
53
+ export { IN_GAME_TYPES, MAX_IN_GAME_SERVER_PICKS, normalizeInGameTypes, normalizeInGameServerIds, } from './other/inGameAlerts';
54
+ export type { InGamePlatform, InGameAlertType, InGameAlert } from './other/inGameAlerts';
55
+ export { forbiddenMiniMessageTag, escapeMiniMessage, safeMiniMessageUrl, NAMED_COLOURS } from './other/inGameMiniMessage';
50
56
  export { GIVEAWAY_CLAIM_WINDOWS, GIVEAWAY_CLAIM_WINDOW_LABELS, GIVEAWAY_MAX_CLAIM_ROUNDS, GIVEAWAY_WINNER_ROLE_MAX_DAYS, GIVEAWAY_MIN_ACCOUNT_AGE_MAX_DAYS, GIVEAWAY_WINNER_ROLE_FORBIDDEN_PERMISSIONS, } from './other/giveawayClaims';
51
57
  export type { GiveawayClaimWindow, GiveawayWinnerStatus } from './other/giveawayClaims';
52
58
  export type { FeatureName, FeatureStatus, ResolvedFeature, } from './other/features';
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.GIVEAWAY_WINNER_ROLE_FORBIDDEN_PERMISSIONS = exports.GIVEAWAY_MIN_ACCOUNT_AGE_MAX_DAYS = exports.GIVEAWAY_WINNER_ROLE_MAX_DAYS = exports.GIVEAWAY_MAX_CLAIM_ROUNDS = exports.GIVEAWAY_CLAIM_WINDOW_LABELS = exports.GIVEAWAY_CLAIM_WINDOWS = exports.OFFLINE_GRACE_PLATFORMS = exports.OFFLINE_GRACE_DEFAULT = exports.OFFLINE_GRACE_CHOICES = exports.FEATURE_NAMES = exports.$Enums = exports.PlatformEnum = exports.StreamerMessageTypeEnum = exports.GuildMessageTypeEnum = void 0;
17
+ exports.GIVEAWAY_WINNER_ROLE_FORBIDDEN_PERMISSIONS = exports.GIVEAWAY_MIN_ACCOUNT_AGE_MAX_DAYS = exports.GIVEAWAY_WINNER_ROLE_MAX_DAYS = exports.GIVEAWAY_MAX_CLAIM_ROUNDS = exports.GIVEAWAY_CLAIM_WINDOW_LABELS = exports.GIVEAWAY_CLAIM_WINDOWS = exports.NAMED_COLOURS = exports.safeMiniMessageUrl = exports.escapeMiniMessage = exports.forbiddenMiniMessageTag = exports.normalizeInGameServerIds = exports.normalizeInGameTypes = exports.MAX_IN_GAME_SERVER_PICKS = exports.IN_GAME_TYPES = exports.hasLivePost = exports.readExtraPosts = exports.extrasFor = exports.normalizeExtraDestinations = exports.MAX_EXTRA_DESTINATIONS = exports.DESTINATION_TYPES = exports.OFFLINE_GRACE_PLATFORMS = exports.OFFLINE_GRACE_DEFAULT = exports.OFFLINE_GRACE_CHOICES = exports.FEATURE_NAMES = exports.$Enums = exports.PlatformEnum = exports.StreamerMessageTypeEnum = exports.GuildMessageTypeEnum = void 0;
18
18
  __exportStar(require("./core/manager"), exports);
19
19
  __exportStar(require("./types"), exports);
20
20
  __exportStar(require("./classes/@me"), exports);
@@ -44,6 +44,7 @@ __exportStar(require("./classes/telemetry"), exports);
44
44
  __exportStar(require("./classes/vods"), exports);
45
45
  __exportStar(require("./classes/guildDrops"), exports);
46
46
  __exportStar(require("./classes/guildBadges"), exports);
47
+ __exportStar(require("./classes/guildInGame"), exports);
47
48
  __exportStar(require("./classes/guildBounties"), exports);
48
49
  __exportStar(require("./classes/guildAssistant"), exports);
49
50
  __exportStar(require("./classes/guildAutoRoles"), exports);
@@ -73,6 +74,23 @@ var offlineGrace_1 = require("./other/offlineGrace");
73
74
  Object.defineProperty(exports, "OFFLINE_GRACE_CHOICES", { enumerable: true, get: function () { return offlineGrace_1.OFFLINE_GRACE_CHOICES; } });
74
75
  Object.defineProperty(exports, "OFFLINE_GRACE_DEFAULT", { enumerable: true, get: function () { return offlineGrace_1.OFFLINE_GRACE_DEFAULT; } });
75
76
  Object.defineProperty(exports, "OFFLINE_GRACE_PLATFORMS", { enumerable: true, get: function () { return offlineGrace_1.OFFLINE_GRACE_PLATFORMS; } });
77
+ var multiDestination_1 = require("./other/multiDestination");
78
+ Object.defineProperty(exports, "DESTINATION_TYPES", { enumerable: true, get: function () { return multiDestination_1.DESTINATION_TYPES; } });
79
+ Object.defineProperty(exports, "MAX_EXTRA_DESTINATIONS", { enumerable: true, get: function () { return multiDestination_1.MAX_EXTRA_DESTINATIONS; } });
80
+ Object.defineProperty(exports, "normalizeExtraDestinations", { enumerable: true, get: function () { return multiDestination_1.normalizeExtraDestinations; } });
81
+ Object.defineProperty(exports, "extrasFor", { enumerable: true, get: function () { return multiDestination_1.extrasFor; } });
82
+ Object.defineProperty(exports, "readExtraPosts", { enumerable: true, get: function () { return multiDestination_1.readExtraPosts; } });
83
+ Object.defineProperty(exports, "hasLivePost", { enumerable: true, get: function () { return multiDestination_1.hasLivePost; } });
84
+ var inGameAlerts_1 = require("./other/inGameAlerts");
85
+ Object.defineProperty(exports, "IN_GAME_TYPES", { enumerable: true, get: function () { return inGameAlerts_1.IN_GAME_TYPES; } });
86
+ Object.defineProperty(exports, "MAX_IN_GAME_SERVER_PICKS", { enumerable: true, get: function () { return inGameAlerts_1.MAX_IN_GAME_SERVER_PICKS; } });
87
+ Object.defineProperty(exports, "normalizeInGameTypes", { enumerable: true, get: function () { return inGameAlerts_1.normalizeInGameTypes; } });
88
+ Object.defineProperty(exports, "normalizeInGameServerIds", { enumerable: true, get: function () { return inGameAlerts_1.normalizeInGameServerIds; } });
89
+ var inGameMiniMessage_1 = require("./other/inGameMiniMessage");
90
+ Object.defineProperty(exports, "forbiddenMiniMessageTag", { enumerable: true, get: function () { return inGameMiniMessage_1.forbiddenMiniMessageTag; } });
91
+ Object.defineProperty(exports, "escapeMiniMessage", { enumerable: true, get: function () { return inGameMiniMessage_1.escapeMiniMessage; } });
92
+ Object.defineProperty(exports, "safeMiniMessageUrl", { enumerable: true, get: function () { return inGameMiniMessage_1.safeMiniMessageUrl; } });
93
+ Object.defineProperty(exports, "NAMED_COLOURS", { enumerable: true, get: function () { return inGameMiniMessage_1.NAMED_COLOURS; } });
76
94
  var giveawayClaims_1 = require("./other/giveawayClaims");
77
95
  Object.defineProperty(exports, "GIVEAWAY_CLAIM_WINDOWS", { enumerable: true, get: function () { return giveawayClaims_1.GIVEAWAY_CLAIM_WINDOWS; } });
78
96
  Object.defineProperty(exports, "GIVEAWAY_CLAIM_WINDOW_LABELS", { enumerable: true, get: function () { return giveawayClaims_1.GIVEAWAY_CLAIM_WINDOW_LABELS; } });