Files
openclaw/extensions/discord/src/monitor/inbound-job.ts
scoootscooob 5682ec37fa refactor: move Discord channel implementation to extensions/ (#45660)
* refactor: move Discord channel implementation to extensions/discord/src/

Move all Discord source files from src/discord/ to extensions/discord/src/,
following the extension migration pattern. Source files in src/discord/ are
replaced with re-export shims. Channel-plugin files from
src/channels/plugins/*/discord* are similarly moved and shimmed.

- Copy all .ts source files preserving subdirectory structure (monitor/, voice/)
- Move channel-plugin files (actions, normalize, onboarding, outbound, status-issues)
- Fix all relative imports to use correct paths from new location
- Create re-export shims at original locations for backward compatibility
- Delete test files from shim locations (tests live in extension now)
- Update tsconfig.plugin-sdk.dts.json rootDir from "src" to "." to accommodate
  extension files outside src/
- Update write-plugin-sdk-entry-dts.ts to match new declaration output paths

* fix: add importOriginal to thread-bindings session-meta mock for extensions test

* style: fix formatting in thread-bindings lifecycle test
2026-03-14 02:53:57 -07:00

112 lines
2.7 KiB
TypeScript

import type { DiscordMessagePreflightContext } from "./message-handler.preflight.types.js";
type DiscordInboundJobRuntimeField =
| "runtime"
| "abortSignal"
| "guildHistories"
| "client"
| "threadBindings"
| "discordRestFetch";
export type DiscordInboundJobRuntime = Pick<
DiscordMessagePreflightContext,
DiscordInboundJobRuntimeField
>;
export type DiscordInboundJobPayload = Omit<
DiscordMessagePreflightContext,
DiscordInboundJobRuntimeField
>;
export type DiscordInboundJob = {
queueKey: string;
payload: DiscordInboundJobPayload;
runtime: DiscordInboundJobRuntime;
};
export function resolveDiscordInboundJobQueueKey(ctx: DiscordMessagePreflightContext): string {
const sessionKey = ctx.route.sessionKey?.trim();
if (sessionKey) {
return sessionKey;
}
const baseSessionKey = ctx.baseSessionKey?.trim();
if (baseSessionKey) {
return baseSessionKey;
}
return ctx.messageChannelId;
}
export function buildDiscordInboundJob(ctx: DiscordMessagePreflightContext): DiscordInboundJob {
const {
runtime,
abortSignal,
guildHistories,
client,
threadBindings,
discordRestFetch,
message,
data,
threadChannel,
...payload
} = ctx;
const sanitizedMessage = sanitizeDiscordInboundMessage(message);
return {
queueKey: resolveDiscordInboundJobQueueKey(ctx),
payload: {
...payload,
message: sanitizedMessage,
data: {
...data,
message: sanitizedMessage,
},
threadChannel: normalizeDiscordThreadChannel(threadChannel),
},
runtime: {
runtime,
abortSignal,
guildHistories,
client,
threadBindings,
discordRestFetch,
},
};
}
export function materializeDiscordInboundJob(
job: DiscordInboundJob,
abortSignal?: AbortSignal,
): DiscordMessagePreflightContext {
return {
...job.payload,
...job.runtime,
abortSignal: abortSignal ?? job.runtime.abortSignal,
};
}
function sanitizeDiscordInboundMessage<T extends object>(message: T): T {
const descriptors = Object.getOwnPropertyDescriptors(message);
delete descriptors.channel;
return Object.create(Object.getPrototypeOf(message), descriptors) as T;
}
function normalizeDiscordThreadChannel(
threadChannel: DiscordMessagePreflightContext["threadChannel"],
): DiscordMessagePreflightContext["threadChannel"] {
if (!threadChannel) {
return null;
}
return {
id: threadChannel.id,
name: threadChannel.name,
parentId: threadChannel.parentId,
parent: threadChannel.parent
? {
id: threadChannel.parent.id,
name: threadChannel.parent.name,
}
: undefined,
ownerId: threadChannel.ownerId,
};
}