@helyx/bot 0.4.2 → 0.4.5
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/CHANGELOG.md +35 -0
- package/README.md +13 -0
- package/dist/cloud-connector.d.ts +7 -0
- package/dist/cloud-connector.js +118 -1
- package/dist/cloud-control-dispatcher.js +84 -0
- package/dist/control-server.d.ts +187 -5
- package/dist/control-server.js +673 -6
- package/dist/developer-operations-module.js +8 -0
- package/dist/discord-owned-message-service.d.ts +39 -0
- package/dist/discord-owned-message-service.js +138 -0
- package/dist/events.d.ts +70 -1
- package/dist/events.js +557 -5
- package/dist/index.js +61 -13
- package/dist/interactions.d.ts +3 -2
- package/dist/interactions.js +66 -31
- package/dist/module-logging.d.ts +1 -0
- package/dist/module-logging.js +19 -1
- package/dist/modules.d.ts +9 -0
- package/dist/modules.js +45 -0
- package/dist/resource-authorization.d.ts +7 -0
- package/dist/resource-authorization.js +12 -0
- package/dist/scheduled-task-runner.d.ts +130 -0
- package/dist/scheduled-task-runner.js +417 -0
- package/dist/shard-cloud-proxy.d.ts +4 -0
- package/dist/shard-cloud-proxy.js +34 -0
- package/dist/shard-contracts.d.ts +574 -23
- package/dist/shard-contracts.js +346 -0
- package/dist/shard-coordinator.d.ts +5 -3
- package/dist/shard-coordinator.js +85 -2
- package/dist/shard-router.d.ts +10 -0
- package/dist/shard-router.js +58 -0
- package/dist/shard-supervisor.d.ts +2 -1
- package/dist/shard-supervisor.js +187 -5
- package/dist/shard-worker.d.ts +9 -3
- package/dist/shard-worker.js +97 -16
- package/dist/support-module.d.ts +9 -0
- package/dist/support-module.js +172 -0
- package/package.json +9 -9
package/dist/shard-worker.js
CHANGED
|
@@ -9,18 +9,22 @@ import { monitorEventLoopDelay } from "node:perf_hooks";
|
|
|
9
9
|
import pino from "pino";
|
|
10
10
|
import { createCloudManagementModule } from "./cloud-management-module.js";
|
|
11
11
|
import { BotControlService, DiscordGuildResourceDirectory, mapBotControlError, } from "./control-server.js";
|
|
12
|
-
import { installModuleEvents } from "./events.js";
|
|
12
|
+
import { DiscordMemberRoleService, DiscordResourceInspection, installModuleEvents, } from "./events.js";
|
|
13
13
|
import { installGuildTracking } from "./guilds.js";
|
|
14
14
|
import { installInteractions, } from "./interactions.js";
|
|
15
15
|
import { createManagementModule } from "./management-module.js";
|
|
16
16
|
import { DiscordModuleLoggingService } from "./module-logging.js";
|
|
17
17
|
import { resolveModulePackageSpecifiers } from "./module-configuration.js";
|
|
18
|
-
import { loadConfiguredModulePackages } from "./modules.js";
|
|
18
|
+
import { loadConfiguredModulePackages, platformServiceOptions, secureRandomSelectionWorkerKeyName, } from "./modules.js";
|
|
19
19
|
import { createPermissionsModule } from "./permissions-module.js";
|
|
20
20
|
import { WorkerCloudConnectorProxy } from "./shard-cloud-proxy.js";
|
|
21
|
+
import { DiscordOwnedMessageDeletionService } from "./discord-owned-message-service.js";
|
|
22
|
+
import { CoreResourceAuthorizationService } from "./resource-authorization.js";
|
|
21
23
|
import { createDeveloperOperationsModule, WorkerShardHealthProvider, } from "./developer-operations-module.js";
|
|
22
24
|
import { assertShardMessageSize, controlOperationGuildId, executeShardControlOperation, guildIdToShardId, SHARD_LEASE_HEARTBEAT_TIMEOUT_MS, shardIdentitySchema, supervisorMessageSchema, } from "./shard-contracts.js";
|
|
23
25
|
import { gatewayIntentsForModules, readBotVersion, } from "./index.js";
|
|
26
|
+
import { createSupportModule } from "./support-module.js";
|
|
27
|
+
import { createLocalScheduledTaskRoute, } from "./scheduled-task-runner.js";
|
|
24
28
|
const HEALTH_INTERVAL_MS = 5_000;
|
|
25
29
|
export const WORKER_ORPHAN_TERMINATION_BOUND_MS = SHARD_LEASE_HEARTBEAT_TIMEOUT_MS + 5_000;
|
|
26
30
|
export function createLeaseHeartbeatWatchdog(onExpired, timeoutMs = SHARD_LEASE_HEARTBEAT_TIMEOUT_MS) {
|
|
@@ -109,10 +113,8 @@ export async function startShardWorker(processEnvironment = process.env, identit
|
|
|
109
113
|
const guildResources = new DiscordGuildResourceDirectory(client);
|
|
110
114
|
const permissionsModule = createPermissionsModule(featureModules);
|
|
111
115
|
const managementModule = createManagementModule(featureModules, guildResources);
|
|
112
|
-
cloudProxy =
|
|
113
|
-
|
|
114
|
-
: undefined;
|
|
115
|
-
const cloudManagementModule = cloudProxy
|
|
116
|
+
cloudProxy = new WorkerCloudConnectorProxy();
|
|
117
|
+
const cloudManagementModule = environment.HELYX_CLOUD_CONNECT_ENABLED
|
|
116
118
|
? createCloudManagementModule({
|
|
117
119
|
connector: cloudProxy,
|
|
118
120
|
client,
|
|
@@ -120,9 +122,11 @@ export async function startShardWorker(processEnvironment = process.env, identit
|
|
|
120
122
|
periodicOwnerRefresh: false,
|
|
121
123
|
})
|
|
122
124
|
: undefined;
|
|
125
|
+
const supportModule = createSupportModule(cloudProxy);
|
|
123
126
|
const publicModules = [
|
|
124
127
|
managementModule,
|
|
125
128
|
permissionsModule,
|
|
129
|
+
supportModule,
|
|
126
130
|
...(cloudManagementModule ? [cloudManagementModule] : []),
|
|
127
131
|
...featureModules,
|
|
128
132
|
];
|
|
@@ -140,6 +144,7 @@ export async function startShardWorker(processEnvironment = process.env, identit
|
|
|
140
144
|
coreFunctions: [
|
|
141
145
|
managementModule,
|
|
142
146
|
permissionsModule,
|
|
147
|
+
supportModule,
|
|
143
148
|
...(cloudManagementModule ? [cloudManagementModule] : []),
|
|
144
149
|
].map(({ manifest }) => manifest),
|
|
145
150
|
modules: featureModules.map(({ manifest }) => manifest),
|
|
@@ -151,14 +156,24 @@ export async function startShardWorker(processEnvironment = process.env, identit
|
|
|
151
156
|
...publicModules,
|
|
152
157
|
...(operationsModule ? [operationsModule] : []),
|
|
153
158
|
];
|
|
154
|
-
const platformServices = new Map(createPlatformServices(database, publicModules));
|
|
159
|
+
const platformServices = new Map(createPlatformServices(database, publicModules, platformServiceOptions(environment, publicModules)));
|
|
160
|
+
platformServices.set(HELYX_SERVICE_NAMES.resourceAuthorization, new CoreResourceAuthorizationService(platformServices.get(HELYX_SERVICE_NAMES.permissions)));
|
|
161
|
+
platformServices.set(HELYX_SERVICE_NAMES.discordOwnedMessages, new DiscordOwnedMessageDeletionService(client));
|
|
162
|
+
platformServices.set(HELYX_SERVICE_NAMES.memberRoles, new DiscordMemberRoleService(client));
|
|
163
|
+
platformServices.set(HELYX_SERVICE_NAMES.discordResources, new DiscordResourceInspection(client));
|
|
155
164
|
if (featureModules.some(({ manifest }) => manifest.id === "helyx.logging"))
|
|
156
165
|
platformServices.set(HELYX_SERVICE_NAMES.moduleLogging, new DiscordModuleLoggingService(client, database, publicModules, logger));
|
|
157
166
|
const serviceAccess = new ServiceRegistry(platformServices);
|
|
167
|
+
const scheduledTaskRoute = createLocalScheduledTaskRoute({
|
|
168
|
+
modules: publicModules,
|
|
169
|
+
services: serviceAccess,
|
|
170
|
+
logger,
|
|
171
|
+
});
|
|
158
172
|
runtime = createRuntime({ modules, logger, services: platformServices });
|
|
159
173
|
const enabledCoreModuleIds = new Set([
|
|
160
174
|
managementModule.manifest.id,
|
|
161
175
|
permissionsModule.manifest.id,
|
|
176
|
+
supportModule.manifest.id,
|
|
162
177
|
...(cloudManagementModule ? [cloudManagementModule.manifest.id] : []),
|
|
163
178
|
...(operationsModule ? [operationsModule.manifest.id] : []),
|
|
164
179
|
]);
|
|
@@ -177,9 +192,16 @@ export async function startShardWorker(processEnvironment = process.env, identit
|
|
|
177
192
|
...(operationsModule
|
|
178
193
|
? { operationsModuleId: operationsModule.manifest.id }
|
|
179
194
|
: {}),
|
|
195
|
+
supportModuleId: supportModule.manifest.id,
|
|
180
196
|
}), logger, serviceAccess);
|
|
181
197
|
moduleEvents = installModuleEvents(client, publicModules, logger, serviceAccess);
|
|
182
|
-
const controlService = new BotControlService(database, publicModules, guildResources, serviceAccess
|
|
198
|
+
const controlService = new BotControlService(database, publicModules, guildResources, serviceAccess, undefined, environment.DISCORD_INTERNAL_GUILD_ID &&
|
|
199
|
+
environment.HELYX_SUPPORT_STAFF_CHANNEL_ID
|
|
200
|
+
? {
|
|
201
|
+
guildId: environment.DISCORD_INTERNAL_GUILD_ID,
|
|
202
|
+
channelId: environment.HELYX_SUPPORT_STAFF_CHANNEL_ID,
|
|
203
|
+
}
|
|
204
|
+
: undefined);
|
|
183
205
|
process.on("message", (raw) => {
|
|
184
206
|
const parsed = supervisorMessageSchema.safeParse(raw);
|
|
185
207
|
if (!parsed.success)
|
|
@@ -200,6 +222,13 @@ export async function startShardWorker(processEnvironment = process.env, identit
|
|
|
200
222
|
else if (parsed.data.type === "helyx.operations.health.response") {
|
|
201
223
|
shardHealthProvider?.accept(parsed.data);
|
|
202
224
|
}
|
|
225
|
+
else if (parsed.data.type === "helyx.scheduled.request") {
|
|
226
|
+
void executeShardScheduledTaskRequest(identity, parsed.data, scheduledTaskRoute).then((response) => {
|
|
227
|
+
assertShardMessageSize(response);
|
|
228
|
+
if (process.connected)
|
|
229
|
+
process.send?.(response);
|
|
230
|
+
});
|
|
231
|
+
}
|
|
203
232
|
else if (parsed.data.type === "helyx.shutdown") {
|
|
204
233
|
void shutdown(parsed.data.reason).finally(() => {
|
|
205
234
|
if (process.connected)
|
|
@@ -236,7 +265,8 @@ export async function startShardWorker(processEnvironment = process.env, identit
|
|
|
236
265
|
client.on(Events.Error, (error) => {
|
|
237
266
|
logger.error({ event: "discord.error", error: safeError(error) }, "Discord shard error");
|
|
238
267
|
});
|
|
239
|
-
|
|
268
|
+
if (environment.HELYX_CLOUD_CONNECT_ENABLED)
|
|
269
|
+
await cloudProxy.start();
|
|
240
270
|
await runtime.start();
|
|
241
271
|
runtimeStarted = true;
|
|
242
272
|
await client.login(environment.DISCORD_TOKEN);
|
|
@@ -253,6 +283,50 @@ export async function startShardWorker(processEnvironment = process.env, identit
|
|
|
253
283
|
throw error;
|
|
254
284
|
}
|
|
255
285
|
}
|
|
286
|
+
export async function executeShardScheduledTaskRequest(identity, request, route, now = Date.now()) {
|
|
287
|
+
const defer = (safeCode) => ({
|
|
288
|
+
version: 1,
|
|
289
|
+
type: "helyx.scheduled.response",
|
|
290
|
+
requestId: request.requestId,
|
|
291
|
+
result: { outcome: "deferred", delayMs: 1_000, safeCode },
|
|
292
|
+
});
|
|
293
|
+
if (!sameShardIdentity(request.identity, identity))
|
|
294
|
+
return defer("stale_owner");
|
|
295
|
+
if (new Date(request.deadlineAt).getTime() <= now)
|
|
296
|
+
return defer("deadline_expired");
|
|
297
|
+
if (guildIdToShardId(request.task.guildId, identity.shardCount) !==
|
|
298
|
+
identity.shardId)
|
|
299
|
+
return defer("wrong_shard");
|
|
300
|
+
const controller = new AbortController();
|
|
301
|
+
const remaining = Math.max(1, new Date(request.deadlineAt).getTime() - now);
|
|
302
|
+
const timer = setTimeout(() => controller.abort(), remaining);
|
|
303
|
+
timer.unref();
|
|
304
|
+
try {
|
|
305
|
+
return {
|
|
306
|
+
version: 1,
|
|
307
|
+
type: "helyx.scheduled.response",
|
|
308
|
+
requestId: request.requestId,
|
|
309
|
+
result: await route(request.task, controller.signal),
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
catch {
|
|
313
|
+
return {
|
|
314
|
+
version: 1,
|
|
315
|
+
type: "helyx.scheduled.response",
|
|
316
|
+
requestId: request.requestId,
|
|
317
|
+
result: {
|
|
318
|
+
outcome: "retry",
|
|
319
|
+
delayMs: 1_000,
|
|
320
|
+
safeCode: controller.signal.aborted
|
|
321
|
+
? "deadline_expired"
|
|
322
|
+
: "handler_failed",
|
|
323
|
+
},
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
finally {
|
|
327
|
+
clearTimeout(timer);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
256
330
|
function sameShardIdentity(left, right) {
|
|
257
331
|
return (left.generation === right.generation &&
|
|
258
332
|
left.deploymentOrder === right.deploymentOrder &&
|
|
@@ -282,7 +356,8 @@ export function parseShardWorkerEnvironment(processEnvironment, identity) {
|
|
|
282
356
|
...(cloudEnabled
|
|
283
357
|
? {
|
|
284
358
|
HELYX_BOT_CONTROL_SECRET: Buffer.alloc(32).toString("base64"),
|
|
285
|
-
HELYX_DATA_ENCRYPTION_KEY:
|
|
359
|
+
HELYX_DATA_ENCRYPTION_KEY: processEnvironment[secureRandomSelectionWorkerKeyName] ??
|
|
360
|
+
Buffer.alloc(32).toString("base64"),
|
|
286
361
|
}
|
|
287
362
|
: {}),
|
|
288
363
|
...(identity.scope === "coordinated"
|
|
@@ -293,7 +368,14 @@ export function parseShardWorkerEnvironment(processEnvironment, identity) {
|
|
|
293
368
|
environment.HELYX_SHARD_MODE !== identity.mode ||
|
|
294
369
|
environment.HELYX_SHARD_SCOPE !== identity.scope)
|
|
295
370
|
throw new Error("Shard worker launch contract conflicts with configuration");
|
|
296
|
-
|
|
371
|
+
const internalSelectionKey = processEnvironment[secureRandomSelectionWorkerKeyName];
|
|
372
|
+
return {
|
|
373
|
+
...environment,
|
|
374
|
+
HELYX_DATA_ENCRYPTION_KEY: undefined,
|
|
375
|
+
...(internalSelectionKey
|
|
376
|
+
? { HELYX_INTERNAL_SECURE_RANDOM_SELECTION_KEY: internalSelectionKey }
|
|
377
|
+
: {}),
|
|
378
|
+
};
|
|
297
379
|
}
|
|
298
380
|
export function shardWorkerCommandRegistration(input) {
|
|
299
381
|
return {
|
|
@@ -302,11 +384,10 @@ export function shardWorkerCommandRegistration(input) {
|
|
|
302
384
|
: {}),
|
|
303
385
|
prepare: input.prepare,
|
|
304
386
|
synchronise: false,
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
: {}),
|
|
387
|
+
selfAuthorizingGuildModuleIds: new Set([
|
|
388
|
+
input.supportModuleId,
|
|
389
|
+
...(input.operationsModuleId ? [input.operationsModuleId] : []),
|
|
390
|
+
]),
|
|
310
391
|
};
|
|
311
392
|
}
|
|
312
393
|
async function handleControl(identity, service, request) {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SupportBugCreatePayload, SupportBugCreateResponsePayload } from "@helyx/control-protocol";
|
|
2
|
+
import { type ModuleDefinition } from "@helyx/sdk";
|
|
3
|
+
export interface SupportBugTransport {
|
|
4
|
+
submitBug(input: SupportBugCreatePayload): Promise<Extract<SupportBugCreateResponsePayload, {
|
|
5
|
+
ok: true;
|
|
6
|
+
}>["result"]>;
|
|
7
|
+
}
|
|
8
|
+
export declare function createSupportModule(transport: SupportBugTransport): ModuleDefinition;
|
|
9
|
+
//# sourceMappingURL=support-module.d.ts.map
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { defineModule, HELYX_SERVICE_NAMES, } from "@helyx/sdk";
|
|
2
|
+
import { randomUUID } from "node:crypto";
|
|
3
|
+
const MODAL_ID = "helyx.support.bug";
|
|
4
|
+
const MODULE_FIELD_ID = "helyx.support.bug.module";
|
|
5
|
+
const SUMMARY_FIELD_ID = "helyx.support.bug.summary";
|
|
6
|
+
const HAPPENED_FIELD_ID = "helyx.support.bug.happened";
|
|
7
|
+
const DETAIL_FIELD_ID = "helyx.support.bug.detail";
|
|
8
|
+
const SUPPORT_URL = "https://app.helyx.gg/support";
|
|
9
|
+
const MODULE_ID = "helyx.support";
|
|
10
|
+
const HOUR_SECONDS = 60 * 60;
|
|
11
|
+
export function createSupportModule(transport) {
|
|
12
|
+
return defineModule({
|
|
13
|
+
manifest: {
|
|
14
|
+
manifestVersion: "0.1",
|
|
15
|
+
releaseStatus: "live",
|
|
16
|
+
id: MODULE_ID,
|
|
17
|
+
name: "Helyx Support",
|
|
18
|
+
version: "0.1.0",
|
|
19
|
+
description: "Provides the always-available Helyx bug report command.",
|
|
20
|
+
entry: "./dist/support-module.js",
|
|
21
|
+
framework: "^0.1.0",
|
|
22
|
+
dependencies: [],
|
|
23
|
+
permissions: [],
|
|
24
|
+
contributions: { commands: ["bug"], events: [] },
|
|
25
|
+
},
|
|
26
|
+
interactions: {
|
|
27
|
+
commands: [
|
|
28
|
+
{
|
|
29
|
+
name: "bug",
|
|
30
|
+
description: "Report a Helyx bug to the support team",
|
|
31
|
+
registration: "global",
|
|
32
|
+
contexts: ["guild"],
|
|
33
|
+
integrationTypes: ["guild_install"],
|
|
34
|
+
async execute(context) {
|
|
35
|
+
await context.showModal({
|
|
36
|
+
customId: MODAL_ID,
|
|
37
|
+
title: "Report a Helyx bug",
|
|
38
|
+
fields: [
|
|
39
|
+
{
|
|
40
|
+
customId: MODULE_FIELD_ID,
|
|
41
|
+
label: "Module or area",
|
|
42
|
+
style: "short",
|
|
43
|
+
required: true,
|
|
44
|
+
minLength: 1,
|
|
45
|
+
maxLength: 100,
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
customId: SUMMARY_FIELD_ID,
|
|
49
|
+
label: "Summary",
|
|
50
|
+
style: "short",
|
|
51
|
+
required: true,
|
|
52
|
+
minLength: 10,
|
|
53
|
+
maxLength: 200,
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
customId: HAPPENED_FIELD_ID,
|
|
57
|
+
label: "What happened?",
|
|
58
|
+
style: "paragraph",
|
|
59
|
+
required: true,
|
|
60
|
+
minLength: 10,
|
|
61
|
+
maxLength: 1_000,
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
customId: DETAIL_FIELD_ID,
|
|
65
|
+
label: "Steps to reproduce or extra detail",
|
|
66
|
+
style: "paragraph",
|
|
67
|
+
required: false,
|
|
68
|
+
maxLength: 1_000,
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
});
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
modals: [
|
|
76
|
+
{
|
|
77
|
+
customId: MODAL_ID,
|
|
78
|
+
async execute(context) {
|
|
79
|
+
if (!context.serverId) {
|
|
80
|
+
await context.reply(notSavedResponse());
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const limits = context.services.get(HELYX_SERVICE_NAMES.rateLimits);
|
|
84
|
+
const userLimit = await limits.consume({
|
|
85
|
+
scope: "user",
|
|
86
|
+
subjectId: context.userId,
|
|
87
|
+
action: `${MODULE_ID}:bug:create:user`,
|
|
88
|
+
limit: 5,
|
|
89
|
+
windowSeconds: HOUR_SECONDS,
|
|
90
|
+
});
|
|
91
|
+
const guildLimit = userLimit.allowed
|
|
92
|
+
? await limits.consume({
|
|
93
|
+
scope: "guild",
|
|
94
|
+
subjectId: context.serverId,
|
|
95
|
+
action: `${MODULE_ID}:bug:create:guild`,
|
|
96
|
+
limit: 20,
|
|
97
|
+
windowSeconds: HOUR_SECONDS,
|
|
98
|
+
})
|
|
99
|
+
: undefined;
|
|
100
|
+
const denied = !userLimit.allowed
|
|
101
|
+
? userLimit
|
|
102
|
+
: guildLimit && !guildLimit.allowed
|
|
103
|
+
? guildLimit
|
|
104
|
+
: undefined;
|
|
105
|
+
if (denied) {
|
|
106
|
+
await context.reply({
|
|
107
|
+
ephemeral: true,
|
|
108
|
+
componentsV2: {
|
|
109
|
+
text: [
|
|
110
|
+
{
|
|
111
|
+
content: `Bug reporting is temporarily rate limited. Try again <t:${Math.ceil(denied.resetsAt.getTime() / 1_000)}:R>.`,
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
await context.deferReply?.(true);
|
|
119
|
+
const detail = context.getField(DETAIL_FIELD_ID).trim();
|
|
120
|
+
try {
|
|
121
|
+
const result = await transport.submitBug({
|
|
122
|
+
operation: "support.bug.create.v1",
|
|
123
|
+
reporterDiscordUserId: context.userId,
|
|
124
|
+
guildId: context.serverId,
|
|
125
|
+
moduleOrArea: context.getField(MODULE_FIELD_ID).trim(),
|
|
126
|
+
summary: context.getField(SUMMARY_FIELD_ID).trim(),
|
|
127
|
+
whatHappened: context.getField(HAPPENED_FIELD_ID).trim(),
|
|
128
|
+
...(detail ? { extraDetail: detail } : {}),
|
|
129
|
+
interactionId: context.interactionId,
|
|
130
|
+
correlationId: randomUUID(),
|
|
131
|
+
});
|
|
132
|
+
await context.reply(successResponse(result));
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
await context.reply(notSavedResponse());
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
],
|
|
140
|
+
},
|
|
141
|
+
start: () => Promise.resolve(),
|
|
142
|
+
stop: () => Promise.resolve(),
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
function successResponse(result) {
|
|
146
|
+
const content = result.claimUrl
|
|
147
|
+
? `Bug report **${result.reference}** has been received from this self-hosted deployment. Use this one-time link to claim it, then track the report and reply through Helyx Support: ${result.claimUrl}`
|
|
148
|
+
: `Bug report **${result.reference}** has been received. You can track the report and reply through Helyx Support: ${SUPPORT_URL}`;
|
|
149
|
+
return {
|
|
150
|
+
ephemeral: true,
|
|
151
|
+
componentsV2: {
|
|
152
|
+
text: [
|
|
153
|
+
{
|
|
154
|
+
content,
|
|
155
|
+
},
|
|
156
|
+
],
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
function notSavedResponse() {
|
|
161
|
+
return {
|
|
162
|
+
ephemeral: true,
|
|
163
|
+
componentsV2: {
|
|
164
|
+
text: [
|
|
165
|
+
{
|
|
166
|
+
content: `The bug report was not saved. Please use the Helyx dashboard: ${SUPPORT_URL}`,
|
|
167
|
+
},
|
|
168
|
+
],
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=support-module.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@helyx/bot",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.5",
|
|
4
4
|
"description": "Production Discord runtime for the modular Helyx platform.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"helyx",
|
|
@@ -48,14 +48,14 @@
|
|
|
48
48
|
"start": "node --env-file-if-exists=../../.env dist/index.js"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@helyx/config": "0.4.
|
|
52
|
-
"@helyx/control-protocol": "0.1.
|
|
53
|
-
"@helyx/core": "0.1.
|
|
54
|
-
"@helyx/database": "0.4.
|
|
55
|
-
"@helyx/framework": "0.1.
|
|
56
|
-
"@helyx/module-manifest": "0.4.
|
|
57
|
-
"@helyx/platform": "0.2.
|
|
58
|
-
"@helyx/sdk": "0.3.
|
|
51
|
+
"@helyx/config": "0.4.2",
|
|
52
|
+
"@helyx/control-protocol": "0.1.4",
|
|
53
|
+
"@helyx/core": "0.1.8",
|
|
54
|
+
"@helyx/database": "0.4.2",
|
|
55
|
+
"@helyx/framework": "0.1.8",
|
|
56
|
+
"@helyx/module-manifest": "0.4.1",
|
|
57
|
+
"@helyx/platform": "0.2.5",
|
|
58
|
+
"@helyx/sdk": "0.3.3",
|
|
59
59
|
"discord.js": "14.27.0",
|
|
60
60
|
"fastify": "5.10.0",
|
|
61
61
|
"pino": "10.3.1",
|