@openclaw/crabline 0.1.12 → 0.1.13
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/README.md +38 -11
- package/dist/src/cli/program.js +17 -2
- package/dist/src/cli/program.js.map +1 -1
- package/dist/src/index.d.ts +12 -10
- package/dist/src/index.js +6 -5
- package/dist/src/index.js.map +1 -1
- package/dist/src/openclaw/artifact-generation.d.ts +5 -9
- package/dist/src/openclaw/artifact-generation.js +41 -69
- package/dist/src/openclaw/artifact-generation.js.map +1 -1
- package/dist/src/openclaw/bridges/discord.d.ts +1 -0
- package/dist/src/openclaw/bridges/discord.js +149 -0
- package/dist/src/openclaw/bridges/discord.js.map +1 -0
- package/dist/src/openclaw/bridges/matrix.js +1 -1
- package/dist/src/openclaw/bridges/matrix.js.map +1 -1
- package/dist/src/openclaw/bridges/mattermost.js +1 -1
- package/dist/src/openclaw/bridges/mattermost.js.map +1 -1
- package/dist/src/openclaw/bridges/signal.js +1 -1
- package/dist/src/openclaw/bridges/signal.js.map +1 -1
- package/dist/src/openclaw/bridges/slack.js +1 -1
- package/dist/src/openclaw/bridges/slack.js.map +1 -1
- package/dist/src/openclaw/bridges/telegram.js +1 -1
- package/dist/src/openclaw/bridges/telegram.js.map +1 -1
- package/dist/src/openclaw/bridges/whatsapp.js +1 -1
- package/dist/src/openclaw/bridges/whatsapp.js.map +1 -1
- package/dist/src/openclaw/bridges/zalo.js +1 -1
- package/dist/src/openclaw/bridges/zalo.js.map +1 -1
- package/dist/src/openclaw/outbound-contract.js +3 -0
- package/dist/src/openclaw/outbound-contract.js.map +1 -1
- package/dist/src/openclaw/{smoke-lock.d.ts → provider-readiness-lock.d.ts} +7 -7
- package/dist/src/openclaw/{smoke-lock.js → provider-readiness-lock.js} +122 -260
- package/dist/src/openclaw/provider-readiness-lock.js.map +1 -0
- package/dist/src/openclaw/shared.d.ts +9 -17
- package/dist/src/openclaw/shared.js +5 -6
- package/dist/src/openclaw/shared.js.map +1 -1
- package/dist/src/openclaw.d.ts +3 -5
- package/dist/src/openclaw.js +22 -20
- package/dist/src/openclaw.js.map +1 -1
- package/dist/src/servers/discord.d.ts +40 -0
- package/dist/src/servers/discord.js +842 -0
- package/dist/src/servers/discord.js.map +1 -0
- package/dist/src/servers/index.d.ts +10 -4
- package/dist/src/servers/index.js +4 -0
- package/dist/src/servers/index.js.map +1 -1
- package/dist/src/servers/slack.js +11 -3
- package/dist/src/servers/slack.js.map +1 -1
- package/dist/src/servers/telegram.js +51 -2
- package/dist/src/servers/telegram.js.map +1 -1
- package/dist/src/servers/whatsapp.d.ts +0 -1
- package/dist/src/servers/whatsapp.js +0 -1
- package/dist/src/servers/whatsapp.js.map +1 -1
- package/docs/channel-setup.md +66 -21
- package/package.json +1 -1
- package/dist/src/openclaw/smoke-lock.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discord.js","sourceRoot":"","sources":["../../../src/servers/discord.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash, randomBytes, randomUUID } from \"node:crypto\";\nimport type { IncomingMessage } from \"node:http\";\nimport path from \"node:path\";\nimport type { Duplex } from \"node:stream\";\nimport { WebSocket, WebSocketServer, type RawData } from \"ws\";\nimport {\n adminAuthError,\n constantTimeTokenEqual,\n hasAdminToken,\n InvalidJsonBodyError,\n isJsonObject,\n isLoopbackHost,\n parseUnknownRequestBody,\n queryRecord,\n readTrimmedString,\n RequestBodyTooLargeError,\n startHttpJsonServer,\n type ServerRequestEvent,\n} from \"./http.js\";\nimport {\n recordCommittedServerEvent,\n recordServerEvent,\n type ServerEventObserver,\n} from \"./recorder.js\";\nimport { closeWebSocketServer } from \"./websocket.js\";\n\nconst DEFAULT_HEARTBEAT_INTERVAL_MS = 45_000;\nconst DEFAULT_IDENTIFY_TIMEOUT_MS = 10_000;\nconst DEFAULT_MAX_GATEWAY_PAYLOAD_BYTES = 4_096;\nconst DISCORD_EPOCH_MS = 1_420_070_400_000n;\nconst DISCORD_ID_PATTERN = /^\\d{17,20}$/u;\n\ntype DiscordUser = {\n avatar: null;\n bot?: boolean;\n discriminator: \"0\";\n global_name: string | null;\n id: string;\n username: string;\n};\n\ntype DiscordChannel = {\n guild_id?: string;\n id: string;\n last_message_id: string | null;\n name?: string;\n parent_id?: string | null;\n recipients?: DiscordUser[];\n type: number;\n};\n\ntype DiscordMessage = {\n allowed_mentions?: unknown;\n attachments: unknown[];\n author: DiscordUser;\n channel_id: string;\n components: unknown[];\n content: string;\n edited_timestamp: null;\n embeds: unknown[];\n flags: number;\n guild_id?: string;\n id: string;\n mention_everyone: boolean;\n mention_roles: string[];\n mentions: DiscordUser[];\n message_reference?: {\n channel_id: string;\n guild_id?: string;\n message_id: string;\n };\n nonce?: string | number;\n pinned: boolean;\n referenced_message?: DiscordMessage | null;\n timestamp: string;\n tts: boolean;\n type: number;\n};\n\ntype DiscordCommand = Record<string, unknown> & {\n application_id: string;\n id: string;\n version: string;\n};\n\ntype GatewayClient = {\n identified: boolean;\n sessionId?: string;\n socket: WebSocket;\n};\n\ntype GatewaySession = {\n lastSequence: number;\n};\n\ntype DiscordServerState = {\n adminToken: string;\n applicationId: string;\n botToken: string;\n botUser: DiscordUser;\n channels: Map<string, DiscordChannel>;\n commands: Map<string, DiscordCommand>;\n gatewayClients: Set<GatewayClient>;\n gatewayUrl?: string;\n guildCommands: Map<string, Map<string, DiscordCommand>>;\n guilds: Map<string, Record<string, unknown>>;\n heartbeatIntervalMs: number;\n identifyTimeoutMs: number;\n maxGatewayPayloadBytes: number;\n messages: Map<string, DiscordMessage[]>;\n nextSequence: number;\n onEvent: ServerEventObserver | undefined;\n pendingRecorderEvents: Set<Promise<void>>;\n recorderPath: string;\n sessions: Map<string, GatewaySession>;\n};\n\ntype DiscordRecorderEvent = ServerRequestEvent & { accepted?: boolean };\n\nexport type DiscordServerManifest = {\n adminToken: string;\n applicationId: string;\n baseUrl: string;\n botToken: string;\n botUserId: string;\n endpoints: {\n adminInboundUrl: string;\n apiRoot: string;\n gatewayBotUrl: string;\n gatewayUrl: string;\n };\n env: {\n DISCORD_BOT_TOKEN: string;\n };\n provider: \"discord\";\n recorderPath: string;\n version: 1;\n};\n\nexport type StartedDiscordServer = {\n close(): Promise<void>;\n manifest: DiscordServerManifest;\n};\n\nexport type StartDiscordServerParams = {\n adminToken?: string | undefined;\n applicationId?: string | undefined;\n botToken?: string | undefined;\n botUserId?: string | undefined;\n botUsername?: string | undefined;\n heartbeatIntervalMs?: number | undefined;\n host?: string | undefined;\n identifyTimeoutMs?: number | undefined;\n maxGatewayPayloadBytes?: number | undefined;\n onEvent?: ServerEventObserver | undefined;\n port?: number | undefined;\n recorderPath?: string | undefined;\n};\n\nfunction discordSnowflake(seed = 0): string {\n const timestamp = BigInt(Math.max(Date.now(), Number(DISCORD_EPOCH_MS))) - DISCORD_EPOCH_MS;\n return ((timestamp << 22n) | BigInt(seed & 0x3f_ffff)).toString();\n}\n\nexport function discordDirectChannelId(botUserId: string, recipientId: string): string {\n if (!DISCORD_ID_PATTERN.test(botUserId) || !DISCORD_ID_PATTERN.test(recipientId)) {\n throw new Error(\"Discord direct channel participants must be Discord snowflakes.\");\n }\n const digest = createHash(\"sha256\")\n .update([botUserId, recipientId].sort().join(\":\"))\n .digest(\"hex\");\n return (\n 100_000_000_000_000_000n +\n (BigInt(`0x${digest.slice(0, 16)}`) % 900_000_000_000_000_000n)\n ).toString();\n}\n\nfunction requireSnowflake(value: unknown, label: string): string {\n const id = readTrimmedString(value);\n if (!id || !DISCORD_ID_PATTERN.test(id)) {\n throw new DiscordRequestError(400, 50_035, `${label} must be a Discord snowflake.`);\n }\n return id;\n}\n\nfunction positiveInteger(value: number | undefined, fallback: number, label: string): number {\n const resolved = value ?? fallback;\n if (!Number.isSafeInteger(resolved) || resolved <= 0) {\n throw new RangeError(`${label} must be a positive safe integer.`);\n }\n return resolved;\n}\n\nclass DiscordRequestError extends Error {\n constructor(\n readonly status: number,\n readonly code: number,\n message: string,\n ) {\n super(message);\n this.name = \"DiscordRequestError\";\n }\n}\n\nfunction discordError(status: number, code: number, message: string): Response {\n return discordJson({ code, message }, status);\n}\n\nfunction rateLimitHeaders(headers?: ConstructorParameters<typeof Headers>[0]): Headers {\n return new Headers({\n \"x-ratelimit-bucket\": \"crabline-discord\",\n \"x-ratelimit-limit\": \"1000\",\n \"x-ratelimit-remaining\": \"999\",\n \"x-ratelimit-reset-after\": \"0\",\n ...Object.fromEntries(new Headers(headers)),\n });\n}\n\nfunction discordJson(value: unknown, status = 200): Response {\n return new Response(JSON.stringify(value), {\n headers: rateLimitHeaders({ \"content-type\": \"application/json\" }),\n status,\n });\n}\n\nfunction discordEmpty(status = 204): Response {\n return new Response(null, { headers: rateLimitHeaders(), status });\n}\n\nfunction authorizationError(request: IncomingMessage, state: DiscordServerState): Response | null {\n const authorization = request.headers.authorization?.trim();\n if (!authorization?.startsWith(\"Bot \")) {\n return new Response(JSON.stringify({ code: 0, message: \"401: Unauthorized\" }), {\n headers: rateLimitHeaders({\n \"content-type\": \"application/json\",\n \"www-authenticate\": 'Bot realm=\"Discord\"',\n }),\n status: 401,\n });\n }\n const token = authorization.slice(4);\n return constantTimeTokenEqual(token, state.botToken)\n ? null\n : new Response(JSON.stringify({ code: 0, message: \"401: Unauthorized\" }), {\n headers: rateLimitHeaders({ \"content-type\": \"application/json\" }),\n status: 401,\n });\n}\n\nfunction discordUser(id: string, username: string, bot = false): DiscordUser {\n return {\n avatar: null,\n ...(bot ? { bot: true } : {}),\n discriminator: \"0\",\n global_name: username,\n id,\n username,\n };\n}\n\nfunction ensureGuild(state: DiscordServerState, guildId: string): Record<string, unknown> {\n const current = state.guilds.get(guildId);\n if (current) {\n return current;\n }\n const guild = {\n afk_timeout: 300,\n channels: [],\n emojis: [],\n features: [],\n id: guildId,\n joined_at: new Date().toISOString(),\n large: false,\n member_count: 1,\n members: [\n {\n deaf: false,\n joined_at: new Date().toISOString(),\n mute: false,\n pending: false,\n roles: [],\n user: state.botUser,\n },\n ],\n name: \"Crabline Discord Guild\",\n owner_id: state.botUser.id,\n presences: [],\n roles: [\n {\n color: 0,\n hoist: false,\n id: guildId,\n managed: false,\n mentionable: false,\n name: \"@everyone\",\n permissions: \"0\",\n position: 0,\n },\n ],\n unavailable: false,\n voice_states: [],\n };\n state.guilds.set(guildId, guild);\n return guild;\n}\n\nfunction ensureChannel(params: {\n channelId: string;\n guildId?: string;\n parentId?: string;\n sender?: DiscordUser;\n state: DiscordServerState;\n}): DiscordChannel {\n const current = params.state.channels.get(params.channelId);\n if (current) {\n return current;\n }\n const channel: DiscordChannel = params.guildId\n ? {\n guild_id: params.guildId,\n id: params.channelId,\n last_message_id: null,\n name: params.parentId ? \"crabline-thread\" : \"crabline-channel\",\n parent_id: params.parentId ?? null,\n type: params.parentId ? 11 : 0,\n }\n : {\n id: params.channelId,\n last_message_id: null,\n recipients: params.sender ? [params.sender] : [],\n type: 1,\n };\n params.state.channels.set(params.channelId, channel);\n if (params.guildId) {\n const guild = ensureGuild(params.state, params.guildId);\n const channels = Array.isArray(guild.channels) ? guild.channels : [];\n guild.channels = [...channels, channel];\n }\n return channel;\n}\n\nfunction parseMentions(content: string, state: DiscordServerState): DiscordUser[] {\n const ids = new Set<string>();\n for (const match of content.matchAll(/<@!?(\\d{17,20})>/gu)) {\n ids.add(match[1]!);\n }\n return [...ids].map((id) =>\n id === state.botUser.id ? state.botUser : discordUser(id, `user-${id.slice(-6)}`),\n );\n}\n\nfunction resolveMessageReference(\n state: DiscordServerState,\n channelId: string,\n value: unknown,\n): DiscordMessage[\"message_reference\"] | undefined {\n if (!isJsonObject(value)) {\n return undefined;\n }\n const messageId = readTrimmedString(value.message_id);\n if (!messageId) {\n return undefined;\n }\n const referencedChannelId = readTrimmedString(value.channel_id) ?? channelId;\n const channel = state.channels.get(referencedChannelId);\n return {\n channel_id: referencedChannelId,\n ...(channel?.guild_id ? { guild_id: channel.guild_id } : {}),\n message_id: messageId,\n };\n}\n\nfunction findMessage(\n state: DiscordServerState,\n channelId: string,\n messageId: string,\n): DiscordMessage | undefined {\n return state.messages.get(channelId)?.find((message) => message.id === messageId);\n}\n\nfunction createMessage(params: {\n author: DiscordUser;\n body: Record<string, unknown>;\n channel: DiscordChannel;\n state: DiscordServerState;\n}): DiscordMessage {\n const content = typeof params.body.content === \"string\" ? params.body.content : \"\";\n const embeds = Array.isArray(params.body.embeds) ? params.body.embeds : [];\n const components = Array.isArray(params.body.components) ? params.body.components : [];\n const attachments = Array.isArray(params.body.attachments) ? params.body.attachments : [];\n if (!content && embeds.length === 0 && components.length === 0 && attachments.length === 0) {\n throw new DiscordRequestError(400, 50_006, \"Cannot send an empty message\");\n }\n if (content.length > 2_000) {\n throw new DiscordRequestError(400, 50_035, \"Invalid Form Body\");\n }\n const reference = resolveMessageReference(\n params.state,\n params.channel.id,\n params.body.message_reference,\n );\n const referencedMessage = reference\n ? (findMessage(params.state, reference.channel_id, reference.message_id) ?? null)\n : undefined;\n const failIfNotExists = isJsonObject(params.body.message_reference)\n ? params.body.message_reference.fail_if_not_exists\n : undefined;\n if (reference && referencedMessage === null && failIfNotExists !== false) {\n throw new DiscordRequestError(404, 10_008, \"Unknown Message\");\n }\n const message: DiscordMessage = {\n ...(params.body.allowed_mentions !== undefined\n ? { allowed_mentions: params.body.allowed_mentions }\n : {}),\n attachments,\n author: params.author,\n channel_id: params.channel.id,\n components,\n content,\n edited_timestamp: null,\n embeds,\n flags: typeof params.body.flags === \"number\" ? params.body.flags : 0,\n ...(params.channel.guild_id ? { guild_id: params.channel.guild_id } : {}),\n id: discordSnowflake(params.state.nextSequence),\n mention_everyone: /@(everyone|here)\\b/u.test(content),\n mention_roles: [...content.matchAll(/<@&(\\d{17,20})>/gu)].map((match) => match[1]!),\n mentions: parseMentions(content, params.state),\n ...(reference\n ? {\n message_reference: reference,\n ...(referencedMessage !== undefined ? { referenced_message: referencedMessage } : {}),\n }\n : {}),\n ...(typeof params.body.nonce === \"string\" || typeof params.body.nonce === \"number\"\n ? { nonce: params.body.nonce }\n : {}),\n pinned: false,\n timestamp: new Date().toISOString(),\n tts: params.body.tts === true,\n type: reference ? 19 : 0,\n };\n params.state.messages.set(params.channel.id, [\n ...(params.state.messages.get(params.channel.id) ?? []),\n message,\n ]);\n params.channel.last_message_id = message.id;\n return message;\n}\n\nfunction sendGatewayPayload(socket: WebSocket, payload: unknown): boolean {\n if (socket.readyState !== WebSocket.OPEN) {\n return false;\n }\n socket.send(JSON.stringify(payload));\n return true;\n}\n\nfunction dispatchGatewayEvent(state: DiscordServerState, type: string, data: unknown): void {\n const payload = { d: data, op: 0, s: state.nextSequence++, t: type };\n for (const client of state.gatewayClients) {\n if (client.identified) {\n sendGatewayPayload(client.socket, payload);\n if (client.sessionId) {\n const session = state.sessions.get(client.sessionId);\n if (session) {\n session.lastSequence = payload.s;\n }\n }\n }\n }\n}\n\nfunction recordGatewayEvent(state: DiscordServerState, body: unknown, accepted: boolean): void {\n const pending = recordCommittedServerEvent({\n event: {\n accepted,\n at: new Date().toISOString(),\n body,\n method: \"WS\",\n path: \"/gateway\",\n query: {},\n type: \"api\",\n } as DiscordRecorderEvent,\n onEvent: state.onEvent,\n recorderPath: state.recorderPath,\n });\n state.pendingRecorderEvents.add(pending);\n void pending.then(\n () => state.pendingRecorderEvents.delete(pending),\n () => state.pendingRecorderEvents.delete(pending),\n );\n}\n\nfunction readyPayload(state: DiscordServerState, sessionId: string) {\n return {\n application: { flags: 0, id: state.applicationId },\n guilds: [...state.guilds.values()].map((guild) => ({ id: guild.id, unavailable: true })),\n resume_gateway_url: state.gatewayUrl!,\n session_id: sessionId,\n user: state.botUser,\n v: 10,\n };\n}\n\nfunction attachGatewayServer(params: {\n server: import(\"node:http\").Server;\n state: DiscordServerState;\n}) {\n const gatewayServer = new WebSocketServer({\n maxPayload: params.state.maxGatewayPayloadBytes,\n noServer: true,\n });\n const onUpgrade = (request: IncomingMessage, socket: Duplex, head: Buffer) => {\n const url = new URL(request.url ?? \"/\", \"http://127.0.0.1\");\n if (url.pathname !== \"/gateway\") {\n socket.destroy();\n return;\n }\n if ((url.searchParams.get(\"v\") ?? \"10\") !== \"10\") {\n socket.destroy();\n return;\n }\n const encoding = url.searchParams.get(\"encoding\") ?? \"json\";\n if (encoding !== \"json\") {\n socket.destroy();\n return;\n }\n gatewayServer.handleUpgrade(request, socket, head, (client) => {\n gatewayServer.emit(\"connection\", client, request);\n });\n };\n params.server.on(\"upgrade\", onUpgrade);\n\n gatewayServer.on(\"connection\", (socket) => {\n const client: GatewayClient = { identified: false, socket };\n params.state.gatewayClients.add(client);\n sendGatewayPayload(socket, {\n d: { heartbeat_interval: params.state.heartbeatIntervalMs },\n op: 10,\n });\n const identifyTimeout = setTimeout(() => {\n if (!client.identified) {\n socket.close(4_003, \"Not authenticated\");\n }\n }, params.state.identifyTimeoutMs);\n identifyTimeout.unref();\n\n socket.on(\"message\", (raw: RawData) => {\n if (Buffer.byteLength(raw.toString()) > params.state.maxGatewayPayloadBytes) {\n socket.close(4_002, \"Decode error\");\n return;\n }\n let payload: unknown;\n try {\n payload = JSON.parse(raw.toString()) as unknown;\n } catch {\n socket.close(4_002, \"Decode error\");\n return;\n }\n if (!isJsonObject(payload) || typeof payload.op !== \"number\") {\n socket.close(4_002, \"Decode error\");\n return;\n }\n recordGatewayEvent(params.state, payload, true);\n if (payload.op === 1) {\n sendGatewayPayload(socket, { d: null, op: 11 });\n return;\n }\n if (payload.op === 2) {\n if (client.identified || !isJsonObject(payload.d)) {\n socket.close(4_005, \"Already authenticated\");\n return;\n }\n const token = readTrimmedString(payload.d.token);\n if (!token || !constantTimeTokenEqual(token, params.state.botToken)) {\n socket.close(4_004, \"Authentication failed\");\n return;\n }\n clearTimeout(identifyTimeout);\n client.identified = true;\n client.sessionId = randomUUID();\n params.state.sessions.set(client.sessionId, { lastSequence: params.state.nextSequence });\n if (params.state.sessions.size > 128) {\n const oldestSessionId = params.state.sessions.keys().next().value as string | undefined;\n if (oldestSessionId) {\n params.state.sessions.delete(oldestSessionId);\n }\n }\n sendGatewayPayload(socket, {\n d: readyPayload(params.state, client.sessionId),\n op: 0,\n s: params.state.nextSequence++,\n t: \"READY\",\n });\n for (const guild of params.state.guilds.values()) {\n dispatchGatewayEvent(params.state, \"GUILD_CREATE\", guild);\n }\n return;\n }\n if (payload.op === 6) {\n if (!isJsonObject(payload.d)) {\n sendGatewayPayload(socket, { d: false, op: 9 });\n return;\n }\n const token = readTrimmedString(payload.d.token);\n const sessionId = readTrimmedString(payload.d.session_id);\n const session = sessionId ? params.state.sessions.get(sessionId) : undefined;\n if (\n !token ||\n !constantTimeTokenEqual(token, params.state.botToken) ||\n !sessionId ||\n !Number.isSafeInteger(payload.d.seq) ||\n (payload.d.seq as number) < 0 ||\n !session ||\n payload.d.seq !== session.lastSequence\n ) {\n sendGatewayPayload(socket, { d: false, op: 9 });\n return;\n }\n clearTimeout(identifyTimeout);\n client.identified = true;\n client.sessionId = sessionId;\n params.state.sessions.delete(sessionId);\n params.state.sessions.set(sessionId, session);\n const resumedSequence = params.state.nextSequence++;\n session.lastSequence = resumedSequence;\n sendGatewayPayload(socket, {\n d: {},\n op: 0,\n s: resumedSequence,\n t: \"RESUMED\",\n });\n return;\n }\n if (payload.op === 3 || payload.op === 4 || payload.op === 8) {\n return;\n }\n socket.close(4_001, \"Unknown opcode\");\n });\n socket.on(\"error\", () => undefined);\n socket.once(\"close\", () => {\n clearTimeout(identifyTimeout);\n params.state.gatewayClients.delete(client);\n });\n });\n\n return async () => {\n params.server.off(\"upgrade\", onUpgrade);\n await closeWebSocketServer(gatewayServer);\n };\n}\n\nfunction commandBody(\n state: DiscordServerState,\n body: Record<string, unknown>,\n existing?: DiscordCommand,\n guildId?: string,\n): DiscordCommand {\n const name = readTrimmedString(body.name ?? existing?.name);\n if (!name || name.length > 32 || !/^[\\w-]+$/u.test(name)) {\n throw new DiscordRequestError(400, 50_035, \"Invalid Form Body\");\n }\n return {\n ...existing,\n ...body,\n application_id: state.applicationId,\n description: readTrimmedString(body.description ?? existing?.description) ?? \"\",\n ...(guildId ? { guild_id: guildId } : {}),\n id: existing?.id ?? discordSnowflake(state.nextSequence++),\n name,\n type: typeof body.type === \"number\" ? body.type : (existing?.type ?? 1),\n version: discordSnowflake(state.nextSequence++),\n };\n}\n\nasync function handleAdminInbound(params: {\n body: Record<string, unknown>;\n state: DiscordServerState;\n}): Promise<Response> {\n const requestedChannelId = requireSnowflake(params.body.channelId, \"channelId\");\n const guildId =\n params.body.guildId === undefined\n ? undefined\n : requireSnowflake(params.body.guildId, \"guildId\");\n const senderId = requireSnowflake(params.body.senderId, \"senderId\");\n const parentChannelId =\n params.body.parentChannelId === undefined\n ? undefined\n : requireSnowflake(params.body.parentChannelId, \"parentChannelId\");\n if (parentChannelId && !guildId) {\n throw new DiscordRequestError(400, 50_035, \"Threads require guildId.\");\n }\n const sender = discordUser(\n senderId,\n readTrimmedString(params.body.senderName) ?? `user-${senderId.slice(-6)}`,\n );\n const hadChannel = params.state.channels.has(requestedChannelId);\n const hadGuild = guildId ? params.state.guilds.has(guildId) : true;\n const channel = ensureChannel({\n channelId: requestedChannelId,\n ...(guildId ? { guildId } : {}),\n ...(parentChannelId ? { parentId: parentChannelId } : {}),\n sender,\n state: params.state,\n });\n const message = createMessage({\n author: sender,\n body: params.body,\n channel,\n state: params.state,\n });\n if (guildId) {\n const guild = params.state.guilds.get(guildId)!;\n const members = Array.isArray(guild.members) ? guild.members : [];\n if (\n !members.some(\n (member) =>\n isJsonObject(member) && isJsonObject(member.user) && member.user.id === sender.id,\n )\n ) {\n members.push({\n deaf: false,\n joined_at: new Date().toISOString(),\n mute: false,\n pending: false,\n roles: [],\n user: sender,\n });\n guild.members = members;\n guild.member_count = members.length;\n }\n (message as DiscordMessage & { member: Record<string, unknown> }).member = {\n deaf: false,\n joined_at: new Date().toISOString(),\n mute: false,\n pending: false,\n roles: [],\n };\n }\n if (!hadGuild && guildId) {\n dispatchGatewayEvent(params.state, \"GUILD_CREATE\", params.state.guilds.get(guildId));\n }\n if (!hadChannel) {\n dispatchGatewayEvent(params.state, \"CHANNEL_CREATE\", channel);\n }\n dispatchGatewayEvent(params.state, \"MESSAGE_CREATE\", message);\n return discordJson({ event: { d: message, op: 0, t: \"MESSAGE_CREATE\" }, message });\n}\n\nasync function handleDiscordApi(params: {\n body: unknown;\n method: string;\n pathname: string;\n state: DiscordServerState;\n}): Promise<Response> {\n const pathParts = params.pathname.split(\"/\").filter(Boolean);\n if (pathParts[0] !== \"api\" || pathParts[1] !== \"v10\") {\n return discordError(404, 0, \"404: Not Found\");\n }\n const route = pathParts.slice(2);\n if (params.method === \"GET\" && route.join(\"/\") === \"users/@me\") {\n return discordJson(params.state.botUser);\n }\n if (params.method === \"GET\" && route.join(\"/\") === \"oauth2/applications/@me\") {\n return discordJson({\n bot: params.state.botUser,\n flags: 0,\n id: params.state.applicationId,\n name: \"Crabline Discord Application\",\n owner: params.state.botUser,\n verify_key: \"crabline\",\n });\n }\n if (params.method === \"GET\" && route.join(\"/\") === \"gateway\") {\n return discordJson({ url: params.state.gatewayUrl });\n }\n if (params.method === \"GET\" && route.join(\"/\") === \"gateway/bot\") {\n return discordJson({\n session_start_limit: {\n max_concurrency: 1,\n remaining: 1_000,\n reset_after: 0,\n total: 1_000,\n },\n shards: 1,\n url: params.state.gatewayUrl,\n });\n }\n if (route[0] === \"channels\" && route.length >= 2) {\n const channelId = requireSnowflake(route[1], \"channel id\");\n const channel = params.state.channels.get(channelId);\n if (route.length === 2 && params.method === \"GET\") {\n return channel ? discordJson(channel) : discordError(404, 10_003, \"Unknown Channel\");\n }\n if (route[2] === \"typing\" && route.length === 3 && params.method === \"POST\") {\n return channel ? discordEmpty() : discordError(404, 10_003, \"Unknown Channel\");\n }\n if (route[2] === \"messages\") {\n if (!channel) {\n return discordError(404, 10_003, \"Unknown Channel\");\n }\n if (route.length === 3 && params.method === \"POST\") {\n if (!isJsonObject(params.body)) {\n throw new InvalidJsonBodyError(undefined, \"Request body must be a JSON object.\");\n }\n const message = createMessage({\n author: params.state.botUser,\n body: params.body,\n channel,\n state: params.state,\n });\n dispatchGatewayEvent(params.state, \"MESSAGE_CREATE\", message);\n return discordJson(message);\n }\n if (route.length === 3 && params.method === \"GET\") {\n return discordJson(\n [...(params.state.messages.get(channelId) ?? [])].reverse().slice(0, 50),\n );\n }\n const messageId = route[3] ? requireSnowflake(route[3], \"message id\") : undefined;\n if (\n messageId &&\n route[4] === \"reactions\" &&\n route[5] &&\n route[6] === \"@me\" &&\n (params.method === \"PUT\" || params.method === \"DELETE\")\n ) {\n return findMessage(params.state, channelId, messageId)\n ? discordEmpty()\n : discordError(404, 10_008, \"Unknown Message\");\n }\n if (messageId && params.method === \"GET\") {\n const message = findMessage(params.state, channelId, messageId);\n return message ? discordJson(message) : discordError(404, 10_008, \"Unknown Message\");\n }\n }\n }\n if (params.method === \"POST\" && route.join(\"/\") === \"users/@me/channels\") {\n if (!isJsonObject(params.body)) {\n throw new InvalidJsonBodyError(undefined, \"Request body must be a JSON object.\");\n }\n const recipientId = requireSnowflake(params.body.recipient_id, \"recipient_id\");\n const recipient = discordUser(recipientId, `user-${recipientId.slice(-6)}`);\n const channelId = discordDirectChannelId(params.state.botUser.id, recipientId);\n return discordJson(ensureChannel({ channelId, sender: recipient, state: params.state }));\n }\n if (route[0] === \"guilds\" && route[1]) {\n const guildId = requireSnowflake(route[1], \"guild id\");\n const guild = params.state.guilds.get(guildId);\n if (!guild) {\n return discordError(404, 10_004, \"Unknown Guild\");\n }\n if (route.length === 2 && params.method === \"GET\") {\n return discordJson(guild);\n }\n if (route[2] === \"channels\" && params.method === \"GET\") {\n return discordJson(\n [...params.state.channels.values()].filter((channel) => channel.guild_id === guildId),\n );\n }\n if (route[2] === \"roles\" && params.method === \"GET\") {\n return discordJson(guild.roles ?? []);\n }\n if (route[2] === \"members\" && route[3] && params.method === \"GET\") {\n const userId = requireSnowflake(route[3], \"user id\");\n const user =\n userId === params.state.botUser.id\n ? params.state.botUser\n : discordUser(userId, `user-${userId.slice(-6)}`);\n return discordJson({\n deaf: false,\n joined_at: new Date().toISOString(),\n mute: false,\n pending: false,\n roles: [],\n user,\n });\n }\n }\n if (route[0] === \"applications\" && route[1] === params.state.applicationId) {\n let commandOffset = 2;\n let guildId: string | undefined;\n if (route[2] === \"guilds\" && route[3] && route[4] === \"commands\") {\n guildId = requireSnowflake(route[3], \"guild id\");\n commandOffset = 4;\n }\n if (route[commandOffset] === \"commands\") {\n const commands = guildId\n ? (params.state.guildCommands.get(guildId) ?? new Map<string, DiscordCommand>())\n : params.state.commands;\n if (guildId && !params.state.guildCommands.has(guildId)) {\n params.state.guildCommands.set(guildId, commands);\n }\n const commandId = route[commandOffset + 1];\n if (!commandId && params.method === \"GET\") {\n return discordJson([...commands.values()]);\n }\n if (!commandId && params.method === \"PUT\") {\n if (!Array.isArray(params.body) || params.body.some((entry) => !isJsonObject(entry))) {\n throw new DiscordRequestError(400, 50_035, \"Invalid Form Body\");\n }\n commands.clear();\n for (const body of params.body as Record<string, unknown>[]) {\n const command = commandBody(params.state, body, undefined, guildId);\n commands.set(command.id, command);\n }\n return discordJson([...commands.values()]);\n }\n if (!commandId && params.method === \"POST\") {\n if (!isJsonObject(params.body)) {\n throw new DiscordRequestError(400, 50_035, \"Invalid Form Body\");\n }\n const name = readTrimmedString(params.body.name);\n const type = typeof params.body.type === \"number\" ? params.body.type : 1;\n const existing = [...commands.values()].find(\n (command) => command.name === name && command.type === type,\n );\n const command = commandBody(params.state, params.body, existing, guildId);\n commands.set(command.id, command);\n return discordJson(command, existing ? 200 : 201);\n }\n if (commandId) {\n const existing = commands.get(commandId);\n if (!existing) {\n return discordError(404, 10_063, \"Unknown application command\");\n }\n if (params.method === \"PATCH\") {\n if (!isJsonObject(params.body)) {\n throw new DiscordRequestError(400, 50_035, \"Invalid Form Body\");\n }\n const command = commandBody(params.state, params.body, existing, guildId);\n commands.set(commandId, command);\n return discordJson(command);\n }\n if (params.method === \"DELETE\") {\n commands.delete(commandId);\n return discordEmpty();\n }\n }\n }\n }\n return discordError(404, 0, \"404: Not Found\");\n}\n\nasync function handleRequest(params: {\n request: IncomingMessage;\n state: DiscordServerState;\n}): Promise<Response> {\n const url = new URL(params.request.url ?? \"/\", \"http://127.0.0.1\");\n const method = params.request.method ?? \"GET\";\n if (url.pathname === \"/crabline/discord/inbound\") {\n if (method !== \"POST\") {\n return new Response(\"not found\", { status: 404 });\n }\n if (!hasAdminToken(params.request, params.state.adminToken)) {\n params.request.resume();\n return adminAuthError();\n }\n const body = await parseUnknownRequestBody(params.request);\n if (!isJsonObject(body)) {\n throw new InvalidJsonBodyError(undefined, \"Request body must be a JSON object.\");\n }\n const event: DiscordRecorderEvent = {\n at: new Date().toISOString(),\n body,\n method,\n path: url.pathname,\n query: queryRecord(url),\n type: \"admin\",\n };\n const response = await handleAdminInbound({ body, state: params.state });\n event.accepted = response.ok;\n await recordCommittedServerEvent({\n event,\n onEvent: params.state.onEvent,\n recorderPath: params.state.recorderPath,\n });\n return response;\n }\n const authError =\n method === \"GET\" && url.pathname === \"/api/v10/gateway\"\n ? null\n : authorizationError(params.request, params.state);\n if (authError) {\n params.request.resume();\n return authError;\n }\n const body =\n method === \"GET\" || method === \"DELETE\" ? {} : await parseUnknownRequestBody(params.request);\n const event: DiscordRecorderEvent = {\n at: new Date().toISOString(),\n ...(isJsonObject(body) && Object.keys(body).length > 0 ? { body } : {}),\n method,\n path: url.pathname,\n query: queryRecord(url),\n type: \"api\",\n };\n const response = await handleDiscordApi({\n body,\n method,\n pathname: url.pathname,\n state: params.state,\n });\n event.accepted = response.ok;\n await (response.ok ? recordCommittedServerEvent : recordServerEvent)({\n event,\n onEvent: params.state.onEvent,\n recorderPath: params.state.recorderPath,\n });\n return response;\n}\n\nexport async function startDiscordServer(\n params: StartDiscordServerParams = {},\n): Promise<StartedDiscordServer> {\n const host = params.host ?? \"127.0.0.1\";\n const applicationId = params.applicationId ?? \"135000000000000001\";\n const botUserId = params.botUserId ?? applicationId;\n requireSnowflake(applicationId, \"applicationId\");\n requireSnowflake(botUserId, \"botUserId\");\n const encodedApplicationId = Buffer.from(applicationId, \"utf8\").toString(\"base64url\");\n const externallyBound = !isLoopbackHost(host);\n const state: DiscordServerState = {\n adminToken: params.adminToken ?? randomBytes(24).toString(\"base64url\"),\n applicationId,\n botToken:\n params.botToken ??\n (externallyBound\n ? `${encodedApplicationId}.${randomBytes(6).toString(\"base64url\")}.${randomBytes(24).toString(\"base64url\")}`\n : `${encodedApplicationId}.crabline.discord`),\n botUser: discordUser(botUserId, params.botUsername ?? \"crabline\", true),\n channels: new Map(),\n commands: new Map(),\n gatewayClients: new Set(),\n guildCommands: new Map(),\n guilds: new Map(),\n heartbeatIntervalMs: positiveInteger(\n params.heartbeatIntervalMs,\n DEFAULT_HEARTBEAT_INTERVAL_MS,\n \"heartbeatIntervalMs\",\n ),\n identifyTimeoutMs: positiveInteger(\n params.identifyTimeoutMs,\n DEFAULT_IDENTIFY_TIMEOUT_MS,\n \"identifyTimeoutMs\",\n ),\n maxGatewayPayloadBytes: positiveInteger(\n params.maxGatewayPayloadBytes,\n DEFAULT_MAX_GATEWAY_PAYLOAD_BYTES,\n \"maxGatewayPayloadBytes\",\n ),\n messages: new Map(),\n nextSequence: 1,\n onEvent: params.onEvent,\n pendingRecorderEvents: new Set(),\n recorderPath: params.recorderPath ?? path.resolve(\".crabline\", \"servers\", \"discord.jsonl\"),\n sessions: new Map(),\n };\n const httpServer = await startHttpJsonServer({\n handle: (request) => handleRequest({ request, state }),\n handleError: (error) => {\n if (error instanceof DiscordRequestError) {\n return discordError(error.status, error.code, error.message);\n }\n if (error instanceof InvalidJsonBodyError) {\n return discordError(400, 50_035, \"Invalid Form Body\");\n }\n if (error instanceof RequestBodyTooLargeError) {\n return discordError(413, 40_005, \"Request entity too large\");\n }\n return undefined;\n },\n host,\n port: params.port ?? 0,\n serverName: \"Discord\",\n });\n state.gatewayUrl = `${httpServer.baseUrl.replace(/^http/u, \"ws\")}/gateway`;\n const closeGateway = attachGatewayServer({ server: httpServer.server, state });\n return {\n async close() {\n await closeGateway();\n await httpServer.close();\n await Promise.all([...state.pendingRecorderEvents]);\n state.sessions.clear();\n },\n manifest: {\n adminToken: state.adminToken,\n applicationId: state.applicationId,\n baseUrl: httpServer.baseUrl,\n botToken: state.botToken,\n botUserId: state.botUser.id,\n endpoints: {\n adminInboundUrl: `${httpServer.baseUrl}/crabline/discord/inbound`,\n apiRoot: `${httpServer.baseUrl}/api`,\n gatewayBotUrl: `${httpServer.baseUrl}/api/v10/gateway/bot`,\n gatewayUrl: state.gatewayUrl,\n },\n env: { DISCORD_BOT_TOKEN: state.botToken },\n provider: \"discord\",\n recorderPath: state.recorderPath,\n version: 1,\n },\n };\n}\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type DiscordServerManifest, type StartedDiscordServer, type StartDiscordServerParams } from "./discord.js";
|
|
1
2
|
import { type MattermostServerManifest, type StartedMattermostServer, type StartMattermostServerParams } from "./mattermost.js";
|
|
2
3
|
import { type MatrixServerManifest, type StartedMatrixServer, type StartMatrixServerParams } from "./matrix.js";
|
|
3
4
|
import { type SignalServerManifest, type StartedSignalServer, type StartSignalServerParams } from "./signal.js";
|
|
@@ -5,11 +6,13 @@ import { type SlackServerManifest, type StartedSlackServer, type StartSlackServe
|
|
|
5
6
|
import { type StartedTelegramServer, type StartTelegramServerParams, type TelegramServerManifest } from "./telegram.js";
|
|
6
7
|
import { type StartedWhatsAppServer, type StartWhatsAppServerParams, type WhatsAppServerManifest } from "./whatsapp.js";
|
|
7
8
|
import { type StartedZaloServer, type StartZaloServerParams, type ZaloServerManifest } from "./zalo.js";
|
|
8
|
-
export declare const CRABLINE_SERVER_CHANNELS: readonly ["mattermost", "matrix", "signal", "slack", "telegram", "whatsapp", "zalo"];
|
|
9
|
+
export declare const CRABLINE_SERVER_CHANNELS: readonly ["discord", "mattermost", "matrix", "signal", "slack", "telegram", "whatsapp", "zalo"];
|
|
9
10
|
export type CrablineServerChannel = (typeof CRABLINE_SERVER_CHANNELS)[number];
|
|
10
|
-
export type CrablineServerManifest = MattermostServerManifest | MatrixServerManifest | SignalServerManifest | SlackServerManifest | TelegramServerManifest | WhatsAppServerManifest | ZaloServerManifest;
|
|
11
|
-
export type StartedCrablineServer = StartedMattermostServer | StartedMatrixServer | StartedSignalServer | StartedSlackServer | StartedTelegramServer | StartedWhatsAppServer | StartedZaloServer;
|
|
12
|
-
export type StartCrablineServerParams = (
|
|
11
|
+
export type CrablineServerManifest = DiscordServerManifest | MattermostServerManifest | MatrixServerManifest | SignalServerManifest | SlackServerManifest | TelegramServerManifest | WhatsAppServerManifest | ZaloServerManifest;
|
|
12
|
+
export type StartedCrablineServer = StartedDiscordServer | StartedMattermostServer | StartedMatrixServer | StartedSignalServer | StartedSlackServer | StartedTelegramServer | StartedWhatsAppServer | StartedZaloServer;
|
|
13
|
+
export type StartCrablineServerParams = (StartDiscordServerParams & {
|
|
14
|
+
channel: "discord";
|
|
15
|
+
}) | (StartMattermostServerParams & {
|
|
13
16
|
channel: "mattermost";
|
|
14
17
|
}) | (StartMatrixServerParams & {
|
|
15
18
|
channel: "matrix";
|
|
@@ -25,6 +28,9 @@ export type StartCrablineServerParams = (StartMattermostServerParams & {
|
|
|
25
28
|
channel: "zalo";
|
|
26
29
|
});
|
|
27
30
|
export declare function isCrablineServerChannel(value: string): value is CrablineServerChannel;
|
|
31
|
+
export declare function startCrablineServer(params: StartDiscordServerParams & {
|
|
32
|
+
channel: "discord";
|
|
33
|
+
}): Promise<StartedDiscordServer>;
|
|
28
34
|
export declare function startCrablineServer(params: StartMattermostServerParams & {
|
|
29
35
|
channel: "mattermost";
|
|
30
36
|
}): Promise<StartedMattermostServer>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { startDiscordServer, } from "./discord.js";
|
|
1
2
|
import { startMattermostServer, } from "./mattermost.js";
|
|
2
3
|
import { startMatrixServer, } from "./matrix.js";
|
|
3
4
|
import { startSignalServer, } from "./signal.js";
|
|
@@ -7,6 +8,7 @@ import { startWhatsAppServer, } from "./whatsapp.js";
|
|
|
7
8
|
import { startZaloServer, } from "./zalo.js";
|
|
8
9
|
import { CrablineError } from "../core/errors.js";
|
|
9
10
|
export const CRABLINE_SERVER_CHANNELS = Object.freeze([
|
|
11
|
+
"discord",
|
|
10
12
|
"mattermost",
|
|
11
13
|
"matrix",
|
|
12
14
|
"signal",
|
|
@@ -21,6 +23,8 @@ export function isCrablineServerChannel(value) {
|
|
|
21
23
|
}
|
|
22
24
|
export async function startCrablineServer(params) {
|
|
23
25
|
switch (params.channel) {
|
|
26
|
+
case "discord":
|
|
27
|
+
return await startDiscordServer(params);
|
|
24
28
|
case "mattermost":
|
|
25
29
|
return await startMattermostServer(params);
|
|
26
30
|
case "matrix":
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/servers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,GAItB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,iBAAiB,GAIlB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,iBAAiB,GAIlB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,gBAAgB,GAIjB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,mBAAmB,GAIpB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,mBAAmB,GAIpB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,eAAe,GAIhB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,MAAM,CAAC,MAAM,wBAAwB,GAAG,MAAM,CAAC,MAAM,CAAC;IACpD,YAAY;IACZ,QAAQ;IACR,QAAQ;IACR,OAAO;IACP,UAAU;IACV,UAAU;IACV,MAAM;CACE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/servers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,GAInB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,qBAAqB,GAItB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,iBAAiB,GAIlB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,iBAAiB,GAIlB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,gBAAgB,GAIjB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,mBAAmB,GAIpB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,mBAAmB,GAIpB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,eAAe,GAIhB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,MAAM,CAAC,MAAM,wBAAwB,GAAG,MAAM,CAAC,MAAM,CAAC;IACpD,SAAS;IACT,YAAY;IACZ,QAAQ;IACR,QAAQ;IACR,OAAO;IACP,UAAU;IACV,UAAU;IACV,MAAM;CACE,CAAC,CAAC;AAkCZ,MAAM,2BAA2B,GAAG,IAAI,GAAG,CAAS,wBAAwB,CAAC,CAAC;AAE9E,MAAM,UAAU,uBAAuB,CAAC,KAAa;IACnD,OAAO,2BAA2B,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAChD,CAAC;AA6BD,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,MAAiC;IAEjC,QAAQ,MAAM,CAAC,OAAO,EAAE,CAAC;QACvB,KAAK,SAAS;YACZ,OAAO,MAAM,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAC1C,KAAK,YAAY;YACf,OAAO,MAAM,qBAAqB,CAAC,MAAM,CAAC,CAAC;QAC7C,KAAK,QAAQ;YACX,OAAO,MAAM,iBAAiB,CAAC,MAAM,CAAC,CAAC;QACzC,KAAK,QAAQ;YACX,OAAO,MAAM,iBAAiB,CAAC,MAAM,CAAC,CAAC;QACzC,KAAK,OAAO;YACV,OAAO,MAAM,gBAAgB,CAAC,MAAM,CAAC,CAAC;QACxC,KAAK,UAAU;YACb,OAAO,MAAM,mBAAmB,CAAC,MAAM,CAAC,CAAC;QAC3C,KAAK,UAAU;YACb,OAAO,MAAM,mBAAmB,CAAC,MAAM,CAAC,CAAC;QAC3C,KAAK,MAAM;YACT,OAAO,MAAM,eAAe,CAAC,MAAM,CAAC,CAAC;QACvC,SAAS,CAAC;YACR,MAAM,WAAW,GAAU,MAAM,CAAC;YAClC,KAAK,WAAW,CAAC;YACjB,MAAM,IAAI,aAAa,CAAC,6BAA6B,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC7E,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import {\n startDiscordServer,\n type DiscordServerManifest,\n type StartedDiscordServer,\n type StartDiscordServerParams,\n} from \"./discord.js\";\nimport {\n startMattermostServer,\n type MattermostServerManifest,\n type StartedMattermostServer,\n type StartMattermostServerParams,\n} from \"./mattermost.js\";\nimport {\n startMatrixServer,\n type MatrixServerManifest,\n type StartedMatrixServer,\n type StartMatrixServerParams,\n} from \"./matrix.js\";\nimport {\n startSignalServer,\n type SignalServerManifest,\n type StartedSignalServer,\n type StartSignalServerParams,\n} from \"./signal.js\";\nimport {\n startSlackServer,\n type SlackServerManifest,\n type StartedSlackServer,\n type StartSlackServerParams,\n} from \"./slack.js\";\nimport {\n startTelegramServer,\n type StartedTelegramServer,\n type StartTelegramServerParams,\n type TelegramServerManifest,\n} from \"./telegram.js\";\nimport {\n startWhatsAppServer,\n type StartedWhatsAppServer,\n type StartWhatsAppServerParams,\n type WhatsAppServerManifest,\n} from \"./whatsapp.js\";\nimport {\n startZaloServer,\n type StartedZaloServer,\n type StartZaloServerParams,\n type ZaloServerManifest,\n} from \"./zalo.js\";\nimport { CrablineError } from \"../core/errors.js\";\n\nexport const CRABLINE_SERVER_CHANNELS = Object.freeze([\n \"discord\",\n \"mattermost\",\n \"matrix\",\n \"signal\",\n \"slack\",\n \"telegram\",\n \"whatsapp\",\n \"zalo\",\n] as const);\n\nexport type CrablineServerChannel = (typeof CRABLINE_SERVER_CHANNELS)[number];\n\nexport type CrablineServerManifest =\n | DiscordServerManifest\n | MattermostServerManifest\n | MatrixServerManifest\n | SignalServerManifest\n | SlackServerManifest\n | TelegramServerManifest\n | WhatsAppServerManifest\n | ZaloServerManifest;\n\nexport type StartedCrablineServer =\n | StartedDiscordServer\n | StartedMattermostServer\n | StartedMatrixServer\n | StartedSignalServer\n | StartedSlackServer\n | StartedTelegramServer\n | StartedWhatsAppServer\n | StartedZaloServer;\n\nexport type StartCrablineServerParams =\n | (StartDiscordServerParams & { channel: \"discord\" })\n | (StartMattermostServerParams & { channel: \"mattermost\" })\n | (StartMatrixServerParams & { channel: \"matrix\" })\n | (StartSignalServerParams & { channel: \"signal\" })\n | (StartSlackServerParams & { channel: \"slack\" })\n | (StartTelegramServerParams & { channel: \"telegram\" })\n | (StartWhatsAppServerParams & { channel: \"whatsapp\" })\n | (StartZaloServerParams & { channel: \"zalo\" });\n\nconst CRABLINE_SERVER_CHANNEL_SET = new Set<string>(CRABLINE_SERVER_CHANNELS);\n\nexport function isCrablineServerChannel(value: string): value is CrablineServerChannel {\n return CRABLINE_SERVER_CHANNEL_SET.has(value);\n}\n\nexport function startCrablineServer(\n params: StartDiscordServerParams & { channel: \"discord\" },\n): Promise<StartedDiscordServer>;\nexport function startCrablineServer(\n params: StartMattermostServerParams & { channel: \"mattermost\" },\n): Promise<StartedMattermostServer>;\nexport function startCrablineServer(\n params: StartMatrixServerParams & { channel: \"matrix\" },\n): Promise<StartedMatrixServer>;\nexport function startCrablineServer(\n params: StartSignalServerParams & { channel: \"signal\" },\n): Promise<StartedSignalServer>;\nexport function startCrablineServer(\n params: StartSlackServerParams & { channel: \"slack\" },\n): Promise<StartedSlackServer>;\nexport function startCrablineServer(\n params: StartTelegramServerParams & { channel: \"telegram\" },\n): Promise<StartedTelegramServer>;\nexport function startCrablineServer(\n params: StartWhatsAppServerParams & { channel: \"whatsapp\" },\n): Promise<StartedWhatsAppServer>;\nexport function startCrablineServer(\n params: StartZaloServerParams & { channel: \"zalo\" },\n): Promise<StartedZaloServer>;\nexport function startCrablineServer(\n params: StartCrablineServerParams,\n): Promise<StartedCrablineServer>;\nexport async function startCrablineServer(\n params: StartCrablineServerParams,\n): Promise<StartedCrablineServer> {\n switch (params.channel) {\n case \"discord\":\n return await startDiscordServer(params);\n case \"mattermost\":\n return await startMattermostServer(params);\n case \"matrix\":\n return await startMatrixServer(params);\n case \"signal\":\n return await startSignalServer(params);\n case \"slack\":\n return await startSlackServer(params);\n case \"telegram\":\n return await startTelegramServer(params);\n case \"whatsapp\":\n return await startWhatsAppServer(params);\n case \"zalo\":\n return await startZaloServer(params);\n default: {\n const unsupported: never = params;\n void unsupported;\n throw new CrablineError(\"Unsupported server channel.\", { kind: \"config\" });\n }\n }\n}\n"]}
|
|
@@ -53,9 +53,17 @@ function resolveChatPostMessageRateLimit(value) {
|
|
|
53
53
|
}
|
|
54
54
|
function requireSlackToken(request, body, state) {
|
|
55
55
|
const authorization = request.headers.authorization;
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
let tokenFromHeader;
|
|
57
|
+
if (typeof authorization === "string") {
|
|
58
|
+
const trimmed = authorization.trim();
|
|
59
|
+
if (trimmed.slice(0, 6).toLowerCase() === "bearer" && /\s/u.test(trimmed[6] ?? "")) {
|
|
60
|
+
let tokenStart = 7;
|
|
61
|
+
while (tokenStart < trimmed.length && /\s/u.test(trimmed[tokenStart])) {
|
|
62
|
+
tokenStart += 1;
|
|
63
|
+
}
|
|
64
|
+
tokenFromHeader = trimmed.slice(tokenStart).trim() || undefined;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
59
67
|
const token = tokenFromHeader ?? readTrimmedString(body.token);
|
|
60
68
|
if (!token) {
|
|
61
69
|
return slackError("not_authed");
|