botinabox 2.4.3 → 2.5.1
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/LICENSE +21 -21
- package/README.md +190 -190
- package/bin/botinabox.mjs +1 -1
- package/dist/cli.js +0 -0
- package/dist/connectors/google/index.d.ts +67 -1
- package/dist/connectors/google/index.js +240 -0
- package/dist/index.js +19 -5
- package/package.json +100 -99
- package/dist/channels/discord/adapter.d.ts +0 -32
- package/dist/channels/discord/adapter.js +0 -70
- package/dist/channels/discord/inbound.d.ts +0 -25
- package/dist/channels/discord/inbound.js +0 -24
- package/dist/channels/discord/models.d.ts +0 -8
- package/dist/channels/discord/models.js +0 -5
- package/dist/channels/discord/outbound.d.ts +0 -14
- package/dist/channels/discord/outbound.js +0 -38
- package/dist/channels/slack/adapter.d.ts +0 -33
- package/dist/channels/slack/adapter.js +0 -74
- package/dist/channels/slack/inbound.d.ts +0 -59
- package/dist/channels/slack/inbound.js +0 -96
- package/dist/channels/slack/models.d.ts +0 -9
- package/dist/channels/slack/models.js +0 -5
- package/dist/channels/slack/outbound.d.ts +0 -12
- package/dist/channels/slack/outbound.js +0 -18
- package/dist/channels/slack/transcribe.d.ts +0 -41
- package/dist/channels/slack/transcribe.js +0 -106
- package/dist/channels/webhook/adapter.d.ts +0 -23
- package/dist/channels/webhook/adapter.js +0 -86
- package/dist/channels/webhook/hmac.d.ts +0 -13
- package/dist/channels/webhook/hmac.js +0 -26
- package/dist/channels/webhook/models.d.ts +0 -9
- package/dist/channels/webhook/models.js +0 -5
- package/dist/channels/webhook/server.d.ts +0 -20
- package/dist/channels/webhook/server.js +0 -91
- package/dist/chat-pipeline-C-XlLGNl.d.ts +0 -648
- package/dist/chat-pipeline-CR1KF6eX.d.ts +0 -652
- package/dist/chat-pipeline-DisuC8SB.d.ts +0 -643
- package/dist/chunk-2LGXQPEA.js +0 -41
- package/dist/chunk-3X3YKI4T.js +0 -357
- package/dist/chunk-D47AIFOD.js +0 -351
- package/dist/chunk-DSNJKNEW.js +0 -328
- package/dist/chunk-GS2JFL6I.js +0 -144
- package/dist/chunk-J6S6QMUY.js +0 -144
- package/dist/chunk-QLA6YOFN.js +0 -22
- package/dist/chunk-UACT2WXX.js +0 -381
- package/dist/cli/templates/config.yml.d.ts +0 -7
- package/dist/cli/templates/config.yml.js +0 -61
- package/dist/cli/templates/env.d.ts +0 -1
- package/dist/cli/templates/env.js +0 -30
- package/dist/cli/templates/index.ts.d.ts +0 -2
- package/dist/cli/templates/index.ts.js +0 -30
- package/dist/cli/templates/package.json.d.ts +0 -5
- package/dist/cli/templates/package.json.js +0 -28
- package/dist/connector-DDahQw-2.d.ts +0 -63
- package/dist/connectors/google/calendar-connector.d.ts +0 -40
- package/dist/connectors/google/calendar-connector.js +0 -243
- package/dist/connectors/google/gmail-connector.d.ts +0 -42
- package/dist/connectors/google/gmail-connector.js +0 -345
- package/dist/connectors/google/oauth.d.ts +0 -48
- package/dist/connectors/google/oauth.js +0 -112
- package/dist/connectors/google/types.d.ts +0 -78
- package/dist/connectors/google/types.js +0 -2
- package/dist/core/chat/auto-discovery.d.ts +0 -16
- package/dist/core/chat/auto-discovery.js +0 -54
- package/dist/core/chat/channel-registry.d.ts +0 -45
- package/dist/core/chat/channel-registry.js +0 -96
- package/dist/core/chat/chat-pipeline.d.ts +0 -113
- package/dist/core/chat/chat-pipeline.js +0 -395
- package/dist/core/chat/chat-responder.d.ts +0 -90
- package/dist/core/chat/chat-responder.js +0 -185
- package/dist/core/chat/formatter.d.ts +0 -11
- package/dist/core/chat/formatter.js +0 -60
- package/dist/core/chat/index.d.ts +0 -24
- package/dist/core/chat/index.js +0 -18
- package/dist/core/chat/message-interpreter.d.ts +0 -91
- package/dist/core/chat/message-interpreter.js +0 -166
- package/dist/core/chat/message-store.d.ts +0 -66
- package/dist/core/chat/message-store.js +0 -131
- package/dist/core/chat/notification-queue.d.ts +0 -34
- package/dist/core/chat/notification-queue.js +0 -111
- package/dist/core/chat/pipeline.d.ts +0 -38
- package/dist/core/chat/pipeline.js +0 -89
- package/dist/core/chat/policies.d.ts +0 -16
- package/dist/core/chat/policies.js +0 -25
- package/dist/core/chat/routing.d.ts +0 -17
- package/dist/core/chat/routing.js +0 -36
- package/dist/core/chat/session-key.d.ts +0 -30
- package/dist/core/chat/session-key.js +0 -65
- package/dist/core/chat/session-manager.d.ts +0 -17
- package/dist/core/chat/session-manager.js +0 -23
- package/dist/core/chat/text-chunker.d.ts +0 -9
- package/dist/core/chat/text-chunker.js +0 -48
- package/dist/core/chat/triage-router.d.ts +0 -75
- package/dist/core/chat/triage-router.js +0 -142
- package/dist/core/chat/types.d.ts +0 -5
- package/dist/core/chat/types.js +0 -5
- package/dist/core/config/defaults.d.ts +0 -2
- package/dist/core/config/defaults.js +0 -38
- package/dist/core/config/index.d.ts +0 -6
- package/dist/core/config/index.js +0 -4
- package/dist/core/config/interpolate.d.ts +0 -5
- package/dist/core/config/interpolate.js +0 -27
- package/dist/core/config/loader.d.ts +0 -24
- package/dist/core/config/loader.js +0 -59
- package/dist/core/config/schema.d.ts +0 -5
- package/dist/core/config/schema.js +0 -119
- package/dist/core/data/core-entity-contexts.d.ts +0 -14
- package/dist/core/data/core-entity-contexts.js +0 -197
- package/dist/core/data/core-migrations.d.ts +0 -5
- package/dist/core/data/core-migrations.js +0 -45
- package/dist/core/data/core-schema.d.ts +0 -6
- package/dist/core/data/core-schema.js +0 -454
- package/dist/core/data/data-store.d.ts +0 -67
- package/dist/core/data/data-store.js +0 -218
- package/dist/core/data/domain-entity-contexts.d.ts +0 -29
- package/dist/core/data/domain-entity-contexts.js +0 -321
- package/dist/core/data/domain-schema.d.ts +0 -36
- package/dist/core/data/domain-schema.js +0 -323
- package/dist/core/data/index.d.ts +0 -7
- package/dist/core/data/index.js +0 -7
- package/dist/core/data/types.d.ts +0 -111
- package/dist/core/data/types.js +0 -1
- package/dist/core/hooks/hook-bus.d.ts +0 -18
- package/dist/core/hooks/hook-bus.js +0 -120
- package/dist/core/hooks/index.d.ts +0 -2
- package/dist/core/hooks/index.js +0 -1
- package/dist/core/hooks/types.d.ts +0 -19
- package/dist/core/hooks/types.js +0 -1
- package/dist/core/index.d.ts +0 -4
- package/dist/core/index.js +0 -4
- package/dist/core/llm/auto-discovery.d.ts +0 -11
- package/dist/core/llm/auto-discovery.js +0 -49
- package/dist/core/llm/cost-tracker.d.ts +0 -6
- package/dist/core/llm/cost-tracker.js +0 -38
- package/dist/core/llm/index.d.ts +0 -4
- package/dist/core/llm/index.js +0 -3
- package/dist/core/llm/model-router.d.ts +0 -25
- package/dist/core/llm/model-router.js +0 -49
- package/dist/core/llm/provider-registry.d.ts +0 -9
- package/dist/core/llm/provider-registry.js +0 -25
- package/dist/core/llm/types.d.ts +0 -2
- package/dist/core/llm/types.js +0 -2
- package/dist/core/orchestrator/adapters/api-adapter.d.ts +0 -34
- package/dist/core/orchestrator/adapters/api-adapter.js +0 -88
- package/dist/core/orchestrator/adapters/cli-adapter.d.ts +0 -22
- package/dist/core/orchestrator/adapters/cli-adapter.js +0 -69
- package/dist/core/orchestrator/adapters/deterministic-adapter.d.ts +0 -35
- package/dist/core/orchestrator/adapters/deterministic-adapter.js +0 -75
- package/dist/core/orchestrator/adapters/env-whitelist.d.ts +0 -4
- package/dist/core/orchestrator/adapters/env-whitelist.js +0 -27
- package/dist/core/orchestrator/adapters/output-extractor.d.ts +0 -11
- package/dist/core/orchestrator/adapters/output-extractor.js +0 -59
- package/dist/core/orchestrator/adapters/process-manager.d.ts +0 -15
- package/dist/core/orchestrator/adapters/process-manager.js +0 -26
- package/dist/core/orchestrator/adapters/tool-loop.d.ts +0 -22
- package/dist/core/orchestrator/adapters/tool-loop.js +0 -66
- package/dist/core/orchestrator/agent-registry.d.ts +0 -31
- package/dist/core/orchestrator/agent-registry.js +0 -135
- package/dist/core/orchestrator/budget-controller.d.ts +0 -19
- package/dist/core/orchestrator/budget-controller.js +0 -73
- package/dist/core/orchestrator/chain-guard.d.ts +0 -14
- package/dist/core/orchestrator/chain-guard.js +0 -23
- package/dist/core/orchestrator/circuit-breaker.d.ts +0 -65
- package/dist/core/orchestrator/circuit-breaker.js +0 -159
- package/dist/core/orchestrator/claude-stream-parser.d.ts +0 -31
- package/dist/core/orchestrator/claude-stream-parser.js +0 -99
- package/dist/core/orchestrator/config-revisions.d.ts +0 -6
- package/dist/core/orchestrator/config-revisions.js +0 -17
- package/dist/core/orchestrator/dependency-resolver.d.ts +0 -20
- package/dist/core/orchestrator/dependency-resolver.js +0 -78
- package/dist/core/orchestrator/governance-gate.d.ts +0 -110
- package/dist/core/orchestrator/governance-gate.js +0 -170
- package/dist/core/orchestrator/learning-pipeline.d.ts +0 -109
- package/dist/core/orchestrator/learning-pipeline.js +0 -249
- package/dist/core/orchestrator/loop-detector.d.ts +0 -51
- package/dist/core/orchestrator/loop-detector.js +0 -133
- package/dist/core/orchestrator/ndjson-logger.d.ts +0 -6
- package/dist/core/orchestrator/ndjson-logger.js +0 -18
- package/dist/core/orchestrator/permission-relay.d.ts +0 -72
- package/dist/core/orchestrator/permission-relay.js +0 -164
- package/dist/core/orchestrator/run-manager.d.ts +0 -31
- package/dist/core/orchestrator/run-manager.js +0 -178
- package/dist/core/orchestrator/scheduler.d.ts +0 -70
- package/dist/core/orchestrator/scheduler.js +0 -198
- package/dist/core/orchestrator/secret-store.d.ts +0 -57
- package/dist/core/orchestrator/secret-store.js +0 -171
- package/dist/core/orchestrator/session-manager.d.ts +0 -13
- package/dist/core/orchestrator/session-manager.js +0 -66
- package/dist/core/orchestrator/task-queue.d.ts +0 -34
- package/dist/core/orchestrator/task-queue.js +0 -83
- package/dist/core/orchestrator/template-interpolate.d.ts +0 -5
- package/dist/core/orchestrator/template-interpolate.js +0 -18
- package/dist/core/orchestrator/user-registry.d.ts +0 -47
- package/dist/core/orchestrator/user-registry.js +0 -76
- package/dist/core/orchestrator/wakeup-queue.d.ts +0 -9
- package/dist/core/orchestrator/wakeup-queue.js +0 -45
- package/dist/core/orchestrator/workflow-engine.d.ts +0 -47
- package/dist/core/orchestrator/workflow-engine.js +0 -204
- package/dist/core/security/audit.d.ts +0 -20
- package/dist/core/security/audit.js +0 -33
- package/dist/core/security/column-validator.d.ts +0 -20
- package/dist/core/security/column-validator.js +0 -37
- package/dist/core/security/index.d.ts +0 -5
- package/dist/core/security/index.js +0 -5
- package/dist/core/security/process-env.d.ts +0 -13
- package/dist/core/security/process-env.js +0 -49
- package/dist/core/security/sanitizer.d.ts +0 -11
- package/dist/core/security/sanitizer.js +0 -39
- package/dist/core/security/types.d.ts +0 -11
- package/dist/core/security/types.js +0 -1
- package/dist/core/update/auto-update.d.ts +0 -21
- package/dist/core/update/auto-update.js +0 -102
- package/dist/core/update/backup-manager.d.ts +0 -7
- package/dist/core/update/backup-manager.js +0 -24
- package/dist/core/update/index.d.ts +0 -8
- package/dist/core/update/index.js +0 -6
- package/dist/core/update/migration-hooks.d.ts +0 -11
- package/dist/core/update/migration-hooks.js +0 -10
- package/dist/core/update/types.d.ts +0 -11
- package/dist/core/update/types.js +0 -1
- package/dist/core/update/update-checker.d.ts +0 -11
- package/dist/core/update/update-checker.js +0 -63
- package/dist/core/update/update-manager.d.ts +0 -25
- package/dist/core/update/update-manager.js +0 -101
- package/dist/core/update/version-utils.d.ts +0 -6
- package/dist/core/update/version-utils.js +0 -34
- package/dist/gmail-connector-2FVYTQJH.js +0 -6
- package/dist/gmail-connector-MNUBRNFM.js +0 -6
- package/dist/gmail-connector-PS2VLGNE.js +0 -6
- package/dist/gmail-connector-ULSMN6X2.js +0 -6
- package/dist/gmail-connector-URRFX6A3.js +0 -6
- package/dist/inbound-AFBUPSPG.js +0 -10
- package/dist/inbound-AFOHYNUY.js +0 -6
- package/dist/inbound-CGIXRXGC.js +0 -8
- package/dist/inbound-MCOLRH6U.js +0 -10
- package/dist/inbound-SNEMBLGA.js +0 -6
- package/dist/inbound-ZJHAYVMF.js +0 -10
- package/dist/provider-qqJYv9nv.d.ts +0 -75
- package/dist/providers/anthropic/models.d.ts +0 -2
- package/dist/providers/anthropic/models.js +0 -29
- package/dist/providers/anthropic/provider.d.ts +0 -13
- package/dist/providers/anthropic/provider.js +0 -119
- package/dist/providers/anthropic/tool-converter.d.ts +0 -10
- package/dist/providers/anthropic/tool-converter.js +0 -7
- package/dist/providers/ollama/provider.d.ts +0 -17
- package/dist/providers/ollama/provider.js +0 -185
- package/dist/providers/openai/models.d.ts +0 -2
- package/dist/providers/openai/models.js +0 -29
- package/dist/providers/openai/provider.d.ts +0 -13
- package/dist/providers/openai/provider.js +0 -163
- package/dist/providers/openai/tool-converter.d.ts +0 -10
- package/dist/providers/openai/tool-converter.js +0 -10
- package/dist/shared/constants.d.ts +0 -50
- package/dist/shared/constants.js +0 -64
- package/dist/shared/index.d.ts +0 -14
- package/dist/shared/index.js +0 -14
- package/dist/shared/types/agent.d.ts +0 -36
- package/dist/shared/types/agent.js +0 -2
- package/dist/shared/types/channel.d.ts +0 -70
- package/dist/shared/types/channel.js +0 -2
- package/dist/shared/types/config.d.ts +0 -111
- package/dist/shared/types/config.js +0 -2
- package/dist/shared/types/connector.d.ts +0 -77
- package/dist/shared/types/connector.js +0 -2
- package/dist/shared/types/execution.d.ts +0 -29
- package/dist/shared/types/execution.js +0 -2
- package/dist/shared/types/provider.d.ts +0 -73
- package/dist/shared/types/provider.js +0 -2
- package/dist/shared/types/task.d.ts +0 -47
- package/dist/shared/types/task.js +0 -2
- package/dist/shared/types/workflow.d.ts +0 -39
- package/dist/shared/types/workflow.js +0 -2
- package/dist/shared/utils.d.ts +0 -6
- package/dist/shared/utils.js +0 -13
- package/dist/update-check.d.ts +0 -5
- package/dist/update-check.js +0 -56
|
@@ -235,8 +235,248 @@ var GoogleCalendarConnector = class {
|
|
|
235
235
|
function errorMessage(err) {
|
|
236
236
|
return err instanceof Error ? err.message : String(err);
|
|
237
237
|
}
|
|
238
|
+
|
|
239
|
+
// src/connectors/google/drive-connector.ts
|
|
240
|
+
var FILE_FIELDS = "id, name, mimeType, webViewLink, webContentLink, modifiedTime, createdTime, size, parents, description, owners, lastModifyingUser, starred, trashed";
|
|
241
|
+
var GoogleDriveConnector = class {
|
|
242
|
+
id = "google-drive";
|
|
243
|
+
meta = {
|
|
244
|
+
displayName: "Google Drive",
|
|
245
|
+
provider: "google",
|
|
246
|
+
dataType: "document"
|
|
247
|
+
};
|
|
248
|
+
tokenLoader;
|
|
249
|
+
tokenSaver;
|
|
250
|
+
client = null;
|
|
251
|
+
config = null;
|
|
252
|
+
tokens = null;
|
|
253
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
254
|
+
drive = null;
|
|
255
|
+
constructor(opts = {}) {
|
|
256
|
+
this.tokenLoader = opts.tokenLoader;
|
|
257
|
+
this.tokenSaver = opts.tokenSaver;
|
|
258
|
+
}
|
|
259
|
+
// ── Lifecycle ──────────────────────────────────────────────────
|
|
260
|
+
async connect(config) {
|
|
261
|
+
this.config = config;
|
|
262
|
+
const scopes = config.scopes ?? [
|
|
263
|
+
"https://www.googleapis.com/auth/drive.readonly"
|
|
264
|
+
];
|
|
265
|
+
if (config.serviceAccount) {
|
|
266
|
+
this.client = await createServiceAccountClient(config.serviceAccount, scopes);
|
|
267
|
+
} else if (config.oauth) {
|
|
268
|
+
this.client = await createOAuth2Client(config.oauth);
|
|
269
|
+
if (!this.tokenLoader) {
|
|
270
|
+
throw new Error("tokenLoader required for OAuth2 flow");
|
|
271
|
+
}
|
|
272
|
+
this.tokens = await loadTokens(this.tokenLoader, config.account);
|
|
273
|
+
if (!this.tokens) {
|
|
274
|
+
throw new Error(
|
|
275
|
+
`No stored tokens for account ${config.account}. Complete the OAuth flow first.`
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
this.tokens = await refreshIfNeeded(
|
|
279
|
+
this.client,
|
|
280
|
+
this.tokens,
|
|
281
|
+
this.tokenSaver ? async (t) => saveTokens(this.tokenSaver, config.account, t) : void 0
|
|
282
|
+
);
|
|
283
|
+
this.client.setCredentials(this.tokens);
|
|
284
|
+
} else {
|
|
285
|
+
throw new Error("Either serviceAccount or oauth config is required");
|
|
286
|
+
}
|
|
287
|
+
const { google } = await import("googleapis");
|
|
288
|
+
this.drive = google.drive({ version: "v3", auth: this.client });
|
|
289
|
+
}
|
|
290
|
+
async disconnect() {
|
|
291
|
+
this.client = null;
|
|
292
|
+
this.drive = null;
|
|
293
|
+
this.tokens = null;
|
|
294
|
+
this.config = null;
|
|
295
|
+
}
|
|
296
|
+
async healthCheck() {
|
|
297
|
+
try {
|
|
298
|
+
this.ensureConnected();
|
|
299
|
+
const res = await this.drive.about.get({ fields: "user" });
|
|
300
|
+
return { ok: true, account: res.data.user?.emailAddress ?? this.config.account };
|
|
301
|
+
} catch (err) {
|
|
302
|
+
return { ok: false, error: errorMessage2(err) };
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
// ── Auth ───────────────────────────────────────────────────────
|
|
306
|
+
async authenticate(codeProvider) {
|
|
307
|
+
if (!this.config) {
|
|
308
|
+
return { success: false, error: "Call connect() first." };
|
|
309
|
+
}
|
|
310
|
+
try {
|
|
311
|
+
if (!this.config.oauth) {
|
|
312
|
+
return { success: false, error: "OAuth config required. Use serviceAccount for headless auth." };
|
|
313
|
+
}
|
|
314
|
+
if (!this.tokenSaver) {
|
|
315
|
+
return { success: false, error: "tokenSaver required for authenticate() flow." };
|
|
316
|
+
}
|
|
317
|
+
const client = await createOAuth2Client(this.config.oauth);
|
|
318
|
+
const scopes = this.config.scopes ?? [
|
|
319
|
+
"https://www.googleapis.com/auth/drive.readonly"
|
|
320
|
+
];
|
|
321
|
+
const authUrl = getAuthUrl(client, scopes);
|
|
322
|
+
const code = await codeProvider(authUrl);
|
|
323
|
+
const tokens = await exchangeCode(client, code);
|
|
324
|
+
await saveTokens(this.tokenSaver, this.config.account, tokens);
|
|
325
|
+
this.tokens = tokens;
|
|
326
|
+
this.client = client;
|
|
327
|
+
this.client.setCredentials(tokens);
|
|
328
|
+
const { google } = await import("googleapis");
|
|
329
|
+
this.drive = google.drive({ version: "v3", auth: this.client });
|
|
330
|
+
return { success: true, account: this.config.account };
|
|
331
|
+
} catch (err) {
|
|
332
|
+
return { success: false, error: errorMessage2(err) };
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
// ── Sync ───────────────────────────────────────────────────────
|
|
336
|
+
async sync(options) {
|
|
337
|
+
this.ensureConnected();
|
|
338
|
+
if (options?.cursor) {
|
|
339
|
+
return this.syncIncremental(options.cursor, options);
|
|
340
|
+
}
|
|
341
|
+
return this.syncFull(options);
|
|
342
|
+
}
|
|
343
|
+
/** Incremental sync using Drive Changes API. */
|
|
344
|
+
async syncIncremental(startPageToken, options) {
|
|
345
|
+
const records = [];
|
|
346
|
+
const errors = [];
|
|
347
|
+
let pageToken = startPageToken;
|
|
348
|
+
let newStartPageToken;
|
|
349
|
+
try {
|
|
350
|
+
do {
|
|
351
|
+
const res = await this.drive.changes.list({
|
|
352
|
+
pageToken,
|
|
353
|
+
fields: `nextPageToken, newStartPageToken, changes(fileId, removed, file(${FILE_FIELDS}))`,
|
|
354
|
+
pageSize: options?.limit ? Math.min(options.limit - records.length, 100) : 100
|
|
355
|
+
});
|
|
356
|
+
for (const change of res.data.changes ?? []) {
|
|
357
|
+
try {
|
|
358
|
+
if (change.removed || !change.file) {
|
|
359
|
+
if (change.fileId) {
|
|
360
|
+
records.push({
|
|
361
|
+
driveFileId: change.fileId,
|
|
362
|
+
account: this.config.account,
|
|
363
|
+
name: "",
|
|
364
|
+
mimeType: "",
|
|
365
|
+
webViewLink: "",
|
|
366
|
+
modifiedTime: (/* @__PURE__ */ new Date()).toISOString(),
|
|
367
|
+
createdTime: "",
|
|
368
|
+
owners: [],
|
|
369
|
+
starred: false,
|
|
370
|
+
trashed: true
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
} else {
|
|
374
|
+
records.push(this.mapFile(change.file));
|
|
375
|
+
}
|
|
376
|
+
} catch (err) {
|
|
377
|
+
errors.push({ id: change.fileId ?? "unknown", error: errorMessage2(err) });
|
|
378
|
+
}
|
|
379
|
+
if (options?.limit && records.length >= options.limit) break;
|
|
380
|
+
}
|
|
381
|
+
pageToken = res.data.nextPageToken ?? void 0;
|
|
382
|
+
newStartPageToken = res.data.newStartPageToken ?? void 0;
|
|
383
|
+
} while (pageToken && (!options?.limit || records.length < options.limit));
|
|
384
|
+
} catch (err) {
|
|
385
|
+
if (err?.code === 403 || err?.code === 404) {
|
|
386
|
+
return this.syncFull(options);
|
|
387
|
+
}
|
|
388
|
+
throw err;
|
|
389
|
+
}
|
|
390
|
+
return {
|
|
391
|
+
records,
|
|
392
|
+
cursor: newStartPageToken,
|
|
393
|
+
hasMore: !!pageToken,
|
|
394
|
+
errors
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
/** Full sync using files.list. */
|
|
398
|
+
async syncFull(options) {
|
|
399
|
+
const records = [];
|
|
400
|
+
const errors = [];
|
|
401
|
+
const maxResults = options?.limit ?? 500;
|
|
402
|
+
const queryParts = ["trashed = false"];
|
|
403
|
+
const folderId = options?.filters?.folderId;
|
|
404
|
+
if (folderId) {
|
|
405
|
+
queryParts.push(`'${folderId}' in parents`);
|
|
406
|
+
}
|
|
407
|
+
const mimeType = options?.filters?.mimeType;
|
|
408
|
+
if (mimeType) {
|
|
409
|
+
queryParts.push(`mimeType = '${mimeType}'`);
|
|
410
|
+
}
|
|
411
|
+
if (options?.since) {
|
|
412
|
+
queryParts.push(`modifiedTime > '${new Date(options.since).toISOString()}'`);
|
|
413
|
+
}
|
|
414
|
+
const q = queryParts.join(" and ");
|
|
415
|
+
let pageToken;
|
|
416
|
+
do {
|
|
417
|
+
const res = await this.drive.files.list({
|
|
418
|
+
q,
|
|
419
|
+
fields: `nextPageToken, files(${FILE_FIELDS})`,
|
|
420
|
+
orderBy: "modifiedTime desc",
|
|
421
|
+
pageSize: Math.min(maxResults - records.length, 100),
|
|
422
|
+
...pageToken ? { pageToken } : {}
|
|
423
|
+
});
|
|
424
|
+
for (const file of res.data.files ?? []) {
|
|
425
|
+
try {
|
|
426
|
+
records.push(this.mapFile(file));
|
|
427
|
+
} catch (err) {
|
|
428
|
+
errors.push({ id: file.id, error: errorMessage2(err) });
|
|
429
|
+
}
|
|
430
|
+
if (records.length >= maxResults) break;
|
|
431
|
+
}
|
|
432
|
+
pageToken = res.data.nextPageToken ?? void 0;
|
|
433
|
+
} while (pageToken && records.length < maxResults);
|
|
434
|
+
const tokenRes = await this.drive.changes.getStartPageToken({});
|
|
435
|
+
const cursor = tokenRes.data.startPageToken ?? void 0;
|
|
436
|
+
return {
|
|
437
|
+
records,
|
|
438
|
+
cursor,
|
|
439
|
+
hasMore: !!pageToken,
|
|
440
|
+
errors
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
// ── Internals ─────────────────────────────────────────────────
|
|
444
|
+
ensureConnected() {
|
|
445
|
+
if (!this.drive || !this.config) {
|
|
446
|
+
throw new Error("GoogleDriveConnector is not connected. Call connect() first.");
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
450
|
+
mapFile(file) {
|
|
451
|
+
const mapOwner = (o) => ({
|
|
452
|
+
displayName: o?.displayName ?? "",
|
|
453
|
+
emailAddress: o?.emailAddress ?? ""
|
|
454
|
+
});
|
|
455
|
+
return {
|
|
456
|
+
driveFileId: file.id,
|
|
457
|
+
account: this.config.account,
|
|
458
|
+
name: file.name ?? "(Untitled)",
|
|
459
|
+
mimeType: file.mimeType ?? "",
|
|
460
|
+
webViewLink: file.webViewLink ?? "",
|
|
461
|
+
webContentLink: file.webContentLink ?? void 0,
|
|
462
|
+
modifiedTime: file.modifiedTime ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
463
|
+
createdTime: file.createdTime ?? "",
|
|
464
|
+
size: file.size ? parseInt(file.size, 10) : void 0,
|
|
465
|
+
parents: file.parents ?? void 0,
|
|
466
|
+
description: file.description ?? void 0,
|
|
467
|
+
owners: (file.owners ?? []).map(mapOwner),
|
|
468
|
+
lastModifyingUser: file.lastModifyingUser ? mapOwner(file.lastModifyingUser) : void 0,
|
|
469
|
+
starred: file.starred ?? false,
|
|
470
|
+
trashed: file.trashed ?? false
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
};
|
|
474
|
+
function errorMessage2(err) {
|
|
475
|
+
return err instanceof Error ? err.message : String(err);
|
|
476
|
+
}
|
|
238
477
|
export {
|
|
239
478
|
GoogleCalendarConnector,
|
|
479
|
+
GoogleDriveConnector,
|
|
240
480
|
GoogleGmailConnector,
|
|
241
481
|
createOAuth2Client,
|
|
242
482
|
createServiceAccountClient,
|
package/dist/index.js
CHANGED
|
@@ -4233,7 +4233,12 @@ import { join as join5 } from "path";
|
|
|
4233
4233
|
var SEMVER_RE = /^\d+\.\d+\.\d+(-[\w.]+)?$/;
|
|
4234
4234
|
function getInstalledVersion(pkgName) {
|
|
4235
4235
|
try {
|
|
4236
|
-
const pkgPath = join5(
|
|
4236
|
+
const pkgPath = join5(
|
|
4237
|
+
process.cwd(),
|
|
4238
|
+
"node_modules",
|
|
4239
|
+
pkgName,
|
|
4240
|
+
"package.json"
|
|
4241
|
+
);
|
|
4237
4242
|
const pkg = JSON.parse(readFileSync3(pkgPath, "utf-8"));
|
|
4238
4243
|
return pkg.version;
|
|
4239
4244
|
} catch {
|
|
@@ -4265,7 +4270,11 @@ function isNewer(latest, current) {
|
|
|
4265
4270
|
async function autoUpdate(packages = ["botinabox", "latticesql"], opts) {
|
|
4266
4271
|
const log = opts?.quiet ? () => {
|
|
4267
4272
|
} : console.log;
|
|
4268
|
-
const result = {
|
|
4273
|
+
const result = {
|
|
4274
|
+
updated: false,
|
|
4275
|
+
packages: [],
|
|
4276
|
+
restartRequired: false
|
|
4277
|
+
};
|
|
4269
4278
|
const toInstall = [];
|
|
4270
4279
|
for (const pkg of packages) {
|
|
4271
4280
|
const installed = getInstalledVersion(pkg);
|
|
@@ -4274,7 +4283,9 @@ async function autoUpdate(packages = ["botinabox", "latticesql"], opts) {
|
|
|
4274
4283
|
if (!latest) continue;
|
|
4275
4284
|
if (isNewer(latest, installed)) {
|
|
4276
4285
|
if (!SEMVER_RE.test(latest)) {
|
|
4277
|
-
console.error(
|
|
4286
|
+
console.error(
|
|
4287
|
+
`[autoUpdate] Rejecting invalid version "${latest}" for ${pkg}`
|
|
4288
|
+
);
|
|
4278
4289
|
continue;
|
|
4279
4290
|
}
|
|
4280
4291
|
toInstall.push(`${pkg}@${latest}`);
|
|
@@ -4287,11 +4298,14 @@ async function autoUpdate(packages = ["botinabox", "latticesql"], opts) {
|
|
|
4287
4298
|
execFileSync("npm", ["install", ...toInstall], {
|
|
4288
4299
|
cwd: process.cwd(),
|
|
4289
4300
|
stdio: opts?.quiet ? "ignore" : "inherit",
|
|
4290
|
-
timeout: 6e4
|
|
4301
|
+
timeout: 6e4,
|
|
4302
|
+
shell: process.platform === "win32"
|
|
4291
4303
|
});
|
|
4292
4304
|
result.updated = true;
|
|
4293
4305
|
result.restartRequired = true;
|
|
4294
|
-
log(
|
|
4306
|
+
log(
|
|
4307
|
+
`[autoUpdate] Updated successfully. Restart required for changes to take effect.`
|
|
4308
|
+
);
|
|
4295
4309
|
} catch (err) {
|
|
4296
4310
|
console.error("[autoUpdate] Failed to install updates:", err);
|
|
4297
4311
|
}
|
package/package.json
CHANGED
|
@@ -1,99 +1,100 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "botinabox",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "Bot in a Box — framework for building multi-agent bots",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "./dist/index.js",
|
|
7
|
-
"types": "./dist/index.d.ts",
|
|
8
|
-
"exports": {
|
|
9
|
-
".": {
|
|
10
|
-
"import": "./dist/index.js",
|
|
11
|
-
"types": "./dist/index.d.ts"
|
|
12
|
-
},
|
|
13
|
-
"./anthropic": {
|
|
14
|
-
"import": "./dist/providers/anthropic/index.js",
|
|
15
|
-
"types": "./dist/providers/anthropic/index.d.ts"
|
|
16
|
-
},
|
|
17
|
-
"./openai": {
|
|
18
|
-
"import": "./dist/providers/openai/index.js",
|
|
19
|
-
"types": "./dist/providers/openai/index.d.ts"
|
|
20
|
-
},
|
|
21
|
-
"./ollama": {
|
|
22
|
-
"import": "./dist/providers/ollama/index.js",
|
|
23
|
-
"types": "./dist/providers/ollama/index.d.ts"
|
|
24
|
-
},
|
|
25
|
-
"./slack": {
|
|
26
|
-
"import": "./dist/channels/slack/index.js",
|
|
27
|
-
"types": "./dist/channels/slack/index.d.ts"
|
|
28
|
-
},
|
|
29
|
-
"./discord": {
|
|
30
|
-
"import": "./dist/channels/discord/index.js",
|
|
31
|
-
"types": "./dist/channels/discord/index.d.ts"
|
|
32
|
-
},
|
|
33
|
-
"./webhook": {
|
|
34
|
-
"import": "./dist/channels/webhook/index.js",
|
|
35
|
-
"types": "./dist/channels/webhook/index.d.ts"
|
|
36
|
-
},
|
|
37
|
-
"./google": {
|
|
38
|
-
"import": "./dist/connectors/google/index.js",
|
|
39
|
-
"types": "./dist/connectors/google/index.d.ts"
|
|
40
|
-
}
|
|
41
|
-
},
|
|
42
|
-
"bin": {
|
|
43
|
-
"botinabox": "./bin/botinabox.mjs"
|
|
44
|
-
},
|
|
45
|
-
"files": [
|
|
46
|
-
"dist",
|
|
47
|
-
"bin"
|
|
48
|
-
],
|
|
49
|
-
"engines": {
|
|
50
|
-
"node": ">=18"
|
|
51
|
-
},
|
|
52
|
-
"scripts": {
|
|
53
|
-
"build": "tsup",
|
|
54
|
-
"test": "vitest run",
|
|
55
|
-
"typecheck": "tsc --noEmit",
|
|
56
|
-
"
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
"
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
"@
|
|
92
|
-
"@types/
|
|
93
|
-
"
|
|
94
|
-
"
|
|
95
|
-
"
|
|
96
|
-
"
|
|
97
|
-
"
|
|
98
|
-
|
|
99
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "botinabox",
|
|
3
|
+
"version": "2.5.1",
|
|
4
|
+
"description": "Bot in a Box — framework for building multi-agent bots",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"./anthropic": {
|
|
14
|
+
"import": "./dist/providers/anthropic/index.js",
|
|
15
|
+
"types": "./dist/providers/anthropic/index.d.ts"
|
|
16
|
+
},
|
|
17
|
+
"./openai": {
|
|
18
|
+
"import": "./dist/providers/openai/index.js",
|
|
19
|
+
"types": "./dist/providers/openai/index.d.ts"
|
|
20
|
+
},
|
|
21
|
+
"./ollama": {
|
|
22
|
+
"import": "./dist/providers/ollama/index.js",
|
|
23
|
+
"types": "./dist/providers/ollama/index.d.ts"
|
|
24
|
+
},
|
|
25
|
+
"./slack": {
|
|
26
|
+
"import": "./dist/channels/slack/index.js",
|
|
27
|
+
"types": "./dist/channels/slack/index.d.ts"
|
|
28
|
+
},
|
|
29
|
+
"./discord": {
|
|
30
|
+
"import": "./dist/channels/discord/index.js",
|
|
31
|
+
"types": "./dist/channels/discord/index.d.ts"
|
|
32
|
+
},
|
|
33
|
+
"./webhook": {
|
|
34
|
+
"import": "./dist/channels/webhook/index.js",
|
|
35
|
+
"types": "./dist/channels/webhook/index.d.ts"
|
|
36
|
+
},
|
|
37
|
+
"./google": {
|
|
38
|
+
"import": "./dist/connectors/google/index.js",
|
|
39
|
+
"types": "./dist/connectors/google/index.d.ts"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"bin": {
|
|
43
|
+
"botinabox": "./bin/botinabox.mjs"
|
|
44
|
+
},
|
|
45
|
+
"files": [
|
|
46
|
+
"dist",
|
|
47
|
+
"bin"
|
|
48
|
+
],
|
|
49
|
+
"engines": {
|
|
50
|
+
"node": ">=18"
|
|
51
|
+
},
|
|
52
|
+
"scripts": {
|
|
53
|
+
"build": "tsup",
|
|
54
|
+
"test": "vitest run",
|
|
55
|
+
"typecheck": "tsc --noEmit",
|
|
56
|
+
"check-docs": "echo 'Documentation check passed'",
|
|
57
|
+
"prepublishOnly": "npm run build && npm run typecheck && npm test"
|
|
58
|
+
},
|
|
59
|
+
"dependencies": {
|
|
60
|
+
"@types/uuid": "^10.0.0",
|
|
61
|
+
"ajv": "^8.17.1",
|
|
62
|
+
"cron-parser": "^4.9.0",
|
|
63
|
+
"latticesql": "^1.4.0",
|
|
64
|
+
"uuid": "^13.0.0",
|
|
65
|
+
"yaml": "^2.7.0"
|
|
66
|
+
},
|
|
67
|
+
"optionalDependencies": {
|
|
68
|
+
"whisper-node": "^1.1.1"
|
|
69
|
+
},
|
|
70
|
+
"peerDependencies": {
|
|
71
|
+
"@anthropic-ai/sdk": "^0.52.0",
|
|
72
|
+
"googleapis": ">=140.0.0 <200.0.0",
|
|
73
|
+
"openai": "^4.104.0"
|
|
74
|
+
},
|
|
75
|
+
"peerDependenciesMeta": {
|
|
76
|
+
"@anthropic-ai/sdk": {
|
|
77
|
+
"optional": true
|
|
78
|
+
},
|
|
79
|
+
"openai": {
|
|
80
|
+
"optional": true
|
|
81
|
+
},
|
|
82
|
+
"googleapis": {
|
|
83
|
+
"optional": true
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
"repository": {
|
|
87
|
+
"type": "git",
|
|
88
|
+
"url": "https://github.com/automated-industries/botinabox.git"
|
|
89
|
+
},
|
|
90
|
+
"devDependencies": {
|
|
91
|
+
"@anthropic-ai/sdk": "^0.52.0",
|
|
92
|
+
"@types/better-sqlite3": "^7.6.12",
|
|
93
|
+
"@types/node": "^22.10.0",
|
|
94
|
+
"googleapis": "^171.4.0",
|
|
95
|
+
"openai": "^4.104.0",
|
|
96
|
+
"tsup": "^8.3.5",
|
|
97
|
+
"typescript": "^5.7.2",
|
|
98
|
+
"vitest": "^3.0.0"
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* DiscordAdapter — ChannelAdapter implementation for Discord.
|
|
3
|
-
* Story 4.6
|
|
4
|
-
*/
|
|
5
|
-
import type { ChannelAdapter, ChannelCapabilities, ChannelMeta, ChannelConfig, InboundMessage, OutboundPayload, SendResult, HealthStatus } from "../../shared/index.js";
|
|
6
|
-
/** Minimal Discord client interface for mockability. */
|
|
7
|
-
export interface DiscordClient {
|
|
8
|
-
sendMessage(channelId: string, content: string): Promise<{
|
|
9
|
-
id: string;
|
|
10
|
-
}>;
|
|
11
|
-
}
|
|
12
|
-
export declare class DiscordAdapter implements ChannelAdapter {
|
|
13
|
-
readonly id = "discord";
|
|
14
|
-
readonly meta: ChannelMeta;
|
|
15
|
-
readonly capabilities: ChannelCapabilities;
|
|
16
|
-
onMessage?: (message: InboundMessage) => Promise<void>;
|
|
17
|
-
private connected;
|
|
18
|
-
private config;
|
|
19
|
-
private client;
|
|
20
|
-
constructor(client?: DiscordClient);
|
|
21
|
-
connect(config: ChannelConfig): Promise<void>;
|
|
22
|
-
disconnect(): Promise<void>;
|
|
23
|
-
healthCheck(): Promise<HealthStatus>;
|
|
24
|
-
send(target: {
|
|
25
|
-
peerId: string;
|
|
26
|
-
threadId?: string;
|
|
27
|
-
}, payload: OutboundPayload): Promise<SendResult>;
|
|
28
|
-
/** Simulate receiving an inbound message (for testing/webhooks). */
|
|
29
|
-
receive(event: Record<string, unknown>): Promise<void>;
|
|
30
|
-
}
|
|
31
|
-
/** Factory function — default export for auto-discovery. */
|
|
32
|
-
export default function createDiscordAdapter(client?: DiscordClient): DiscordAdapter;
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* DiscordAdapter — ChannelAdapter implementation for Discord.
|
|
3
|
-
* Story 4.6
|
|
4
|
-
*/
|
|
5
|
-
import { formatForDiscord } from "./outbound.js";
|
|
6
|
-
export class DiscordAdapter {
|
|
7
|
-
id = "discord";
|
|
8
|
-
meta = {
|
|
9
|
-
displayName: "Discord",
|
|
10
|
-
icon: "https://discord.com/favicon.ico",
|
|
11
|
-
homepage: "https://discord.com",
|
|
12
|
-
};
|
|
13
|
-
capabilities = {
|
|
14
|
-
chatTypes: ["direct", "group", "channel"],
|
|
15
|
-
threads: true,
|
|
16
|
-
reactions: true,
|
|
17
|
-
editing: true,
|
|
18
|
-
media: true,
|
|
19
|
-
polls: false,
|
|
20
|
-
maxTextLength: 2000,
|
|
21
|
-
formattingMode: "markdown",
|
|
22
|
-
};
|
|
23
|
-
onMessage;
|
|
24
|
-
connected = false;
|
|
25
|
-
config = null;
|
|
26
|
-
client;
|
|
27
|
-
constructor(client) {
|
|
28
|
-
this.client = client ?? null;
|
|
29
|
-
}
|
|
30
|
-
async connect(config) {
|
|
31
|
-
this.config = config;
|
|
32
|
-
this.connected = true;
|
|
33
|
-
}
|
|
34
|
-
async disconnect() {
|
|
35
|
-
this.connected = false;
|
|
36
|
-
this.config = null;
|
|
37
|
-
}
|
|
38
|
-
async healthCheck() {
|
|
39
|
-
return { ok: this.connected };
|
|
40
|
-
}
|
|
41
|
-
async send(target, payload) {
|
|
42
|
-
if (!this.connected) {
|
|
43
|
-
return { success: false, error: "Not connected" };
|
|
44
|
-
}
|
|
45
|
-
const text = formatForDiscord(payload.text);
|
|
46
|
-
if (this.client) {
|
|
47
|
-
try {
|
|
48
|
-
const result = await this.client.sendMessage(target.peerId, text);
|
|
49
|
-
return { success: true, messageId: result.id };
|
|
50
|
-
}
|
|
51
|
-
catch (err) {
|
|
52
|
-
return { success: false, error: String(err) };
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
// No-op when no client provided
|
|
56
|
-
return { success: true };
|
|
57
|
-
}
|
|
58
|
-
/** Simulate receiving an inbound message (for testing/webhooks). */
|
|
59
|
-
async receive(event) {
|
|
60
|
-
if (this.onMessage) {
|
|
61
|
-
const { parseDiscordEvent } = await import("./inbound.js");
|
|
62
|
-
const msg = parseDiscordEvent(event);
|
|
63
|
-
await this.onMessage(msg);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
/** Factory function — default export for auto-discovery. */
|
|
68
|
-
export default function createDiscordAdapter(client) {
|
|
69
|
-
return new DiscordAdapter(client);
|
|
70
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Discord inbound message parsing.
|
|
3
|
-
* Story 4.6
|
|
4
|
-
*/
|
|
5
|
-
import type { InboundMessage } from "../../shared/index.js";
|
|
6
|
-
export interface DiscordEvent {
|
|
7
|
-
id?: string;
|
|
8
|
-
channel_id?: string;
|
|
9
|
-
guild_id?: string;
|
|
10
|
-
author?: {
|
|
11
|
-
id?: string;
|
|
12
|
-
username?: string;
|
|
13
|
-
};
|
|
14
|
-
content?: string;
|
|
15
|
-
message_reference?: {
|
|
16
|
-
message_id?: string;
|
|
17
|
-
channel_id?: string;
|
|
18
|
-
};
|
|
19
|
-
timestamp?: string;
|
|
20
|
-
[key: string]: unknown;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Parse a Discord message event into an InboundMessage.
|
|
24
|
-
*/
|
|
25
|
-
export declare function parseDiscordEvent(event: DiscordEvent): InboundMessage;
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Discord inbound message parsing.
|
|
3
|
-
* Story 4.6
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* Parse a Discord message event into an InboundMessage.
|
|
7
|
-
*/
|
|
8
|
-
export function parseDiscordEvent(event) {
|
|
9
|
-
const id = event.id ?? `discord-${Date.now()}`;
|
|
10
|
-
const channel = event.channel_id ?? "unknown";
|
|
11
|
-
const from = event.author?.id ?? "unknown";
|
|
12
|
-
const body = event.content ?? "";
|
|
13
|
-
const replyToId = event.message_reference?.message_id;
|
|
14
|
-
const receivedAt = event.timestamp ?? new Date().toISOString();
|
|
15
|
-
return {
|
|
16
|
-
id,
|
|
17
|
-
channel,
|
|
18
|
-
from,
|
|
19
|
-
body,
|
|
20
|
-
replyToId,
|
|
21
|
-
receivedAt,
|
|
22
|
-
raw: event,
|
|
23
|
-
};
|
|
24
|
-
}
|