openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
263 lines (262 loc) • 11 kB
JavaScript
import { l as normalizeOptionalStringifiedId } from "./string-coerce-mnp54Vah.js";
import { c as normalizeInteractiveReply, l as normalizeMessagePresentation } from "./payload-CZlThETZ.js";
import { b as readStringParam, g as readPositiveIntegerParam, v as readStringArrayParam } from "./common-C4yy9V-D.js";
import { t as readBooleanParam } from "./boolean-param-K-k-cDXs.js";
import "./string-coerce-runtime-CEGJWkQ_.js";
import "./agent-runtime-CvpQRNVf.js";
import { r as resolveReactionMessageId } from "./channel-actions-BOfvC-Gl.js";
import { n as resolveDiscordChannelId } from "./target-parsing-CxulEx_f.js";
import { t as handleDiscordAction } from "./runtime-BismxRuL.js";
import { n as buildDiscordPresentationComponents, t as buildDiscordInteractiveComponents } from "./shared-interactive-Dw8ye7mU.js";
import "./targets-B5qkz8Y1.js";
import "./action-runtime-api-CdxCjrx4.js";
import { r as notifyDiscordInboundEventOutboundSuccess } from "./inbound-event-delivery-BI9WnEey.js";
import { t as tryHandleDiscordMessageActionGuildAdmin } from "./handle-action.guild-admin-CAarAX8Z.js";
//#region extensions/discord/src/actions/handle-action.ts
const providerId = "discord";
function readCurrentDiscordTarget(toolContext) {
const provider = toolContext?.currentChannelProvider?.trim().toLowerCase();
if (provider && provider !== providerId) return;
return toolContext?.currentChannelId?.trim() || void 0;
}
async function handleDiscordMessageAction(ctx) {
const { action, params, cfg } = ctx;
const accountId = ctx.accountId ?? readStringParam(params, "accountId");
const actionOptions = {
mediaAccess: ctx.mediaAccess,
mediaLocalRoots: ctx.mediaLocalRoots,
mediaReadFile: ctx.mediaReadFile
};
const notifyVisibleOutbound = (to, fallbackSessionKey) => notifyDiscordInboundEventOutboundSuccess({
sessionKey: ctx.sessionKey ?? fallbackSessionKey ?? void 0,
to,
accountId,
inboundEventKind: ctx.inboundEventKind
});
const readTarget = () => {
const target = readStringParam(params, "channelId") ?? readStringParam(params, "to") ?? readCurrentDiscordTarget(ctx.toolContext);
if (!target) throw new Error("Discord channel target is required (use channel:<id>).");
return target;
};
const resolveChannelId = () => resolveDiscordChannelId(readTarget());
const readSendTarget = () => {
const target = readStringParam(params, "to") ?? readStringParam(params, "target") ?? readCurrentDiscordTarget(ctx.toolContext);
if (!target) throw new Error("Discord channel target is required (use channel:<id>).");
return target;
};
if (action === "send") {
const to = readSendTarget();
const asVoice = readBooleanParam(params, "asVoice") === true;
const rawComponents = params.components ?? buildDiscordPresentationComponents(normalizeMessagePresentation(params.presentation)) ?? buildDiscordInteractiveComponents(normalizeInteractiveReply(params.interactive));
const hasComponents = Boolean(rawComponents) && (typeof rawComponents === "function" || typeof rawComponents === "object");
const components = hasComponents ? rawComponents : void 0;
const mediaUrl = readStringParam(params, "media", { trim: false }) ?? readStringParam(params, "path", { trim: false }) ?? readStringParam(params, "filePath", { trim: false });
const content = readStringParam(params, "message", {
required: !asVoice && !hasComponents && !mediaUrl,
allowEmpty: true
});
const filename = readStringParam(params, "filename");
const replyTo = readStringParam(params, "replyTo");
const rawEmbeds = params.embeds;
const embeds = Array.isArray(rawEmbeds) ? rawEmbeds : void 0;
const silent = readBooleanParam(params, "silent") === true;
const suppressEmbeds = readBooleanParam(params, "suppressEmbeds");
const sessionKey = readStringParam(params, "__sessionKey");
const agentId = readStringParam(params, "__agentId");
const threadName = readStringParam(params, "threadName");
const result = await handleDiscordAction({
action: "sendMessage",
accountId: accountId ?? void 0,
to,
content: content ?? "",
...threadName ? { threadName } : {},
mediaUrl: mediaUrl ?? void 0,
filename: filename ?? void 0,
replyTo: replyTo ?? void 0,
components,
embeds,
asVoice,
silent,
...suppressEmbeds === void 0 ? {} : { suppressEmbeds },
__sessionKey: sessionKey ?? void 0,
__agentId: agentId ?? void 0
}, cfg, actionOptions);
notifyVisibleOutbound(to, sessionKey);
return result;
}
if (action === "upload-file") {
const to = readSendTarget();
const mediaUrl = readStringParam(params, "filePath", { trim: false }) ?? readStringParam(params, "path", { trim: false }) ?? readStringParam(params, "media", { trim: false });
if (!mediaUrl) throw new Error("upload-file requires filePath, path, or media.");
const content = readStringParam(params, "message", { allowEmpty: true }) ?? readStringParam(params, "content", { allowEmpty: true });
const filename = readStringParam(params, "filename");
const replyTo = readStringParam(params, "replyTo");
const silent = readBooleanParam(params, "silent") === true;
const suppressEmbeds = readBooleanParam(params, "suppressEmbeds");
const sessionKey = readStringParam(params, "__sessionKey");
const agentId = readStringParam(params, "__agentId");
const result = await handleDiscordAction({
action: "sendMessage",
accountId: accountId ?? void 0,
to,
content: content ?? "",
mediaUrl,
filename: filename ?? void 0,
replyTo: replyTo ?? void 0,
silent,
...suppressEmbeds === void 0 ? {} : { suppressEmbeds },
__sessionKey: sessionKey ?? void 0,
__agentId: agentId ?? void 0
}, cfg, actionOptions);
notifyVisibleOutbound(to, sessionKey);
return result;
}
if (action === "poll") {
const to = readStringParam(params, "to", { required: true });
const question = readStringParam(params, "pollQuestion", { required: true });
const answers = readStringArrayParam(params, "pollOption", { required: true });
const allowMultiselect = readBooleanParam(params, "pollMulti");
const durationHours = readPositiveIntegerParam(params, "pollDurationHours");
const result = await handleDiscordAction({
action: "poll",
accountId: accountId ?? void 0,
to,
question,
answers,
allowMultiselect,
durationHours: durationHours ?? void 0,
content: readStringParam(params, "message")
}, cfg, actionOptions);
notifyVisibleOutbound(to);
return result;
}
if (action === "react") {
const messageId = normalizeOptionalStringifiedId(resolveReactionMessageId({
args: params,
toolContext: ctx.toolContext
})) ?? "";
if (!messageId) throw new Error("messageId required. Provide messageId explicitly or react to the current inbound message.");
const emoji = readStringParam(params, "emoji", { allowEmpty: true });
const remove = readBooleanParam(params, "remove");
return await handleDiscordAction({
action: "react",
accountId: accountId ?? void 0,
channelId: readTarget(),
messageId,
emoji,
remove
}, cfg, actionOptions);
}
if (action === "reactions") {
const messageId = readStringParam(params, "messageId", { required: true });
const limit = readPositiveIntegerParam(params, "limit");
return await handleDiscordAction({
action: "reactions",
accountId: accountId ?? void 0,
channelId: readTarget(),
messageId,
limit
}, cfg, actionOptions);
}
if (action === "read") {
const limit = readPositiveIntegerParam(params, "limit");
return await handleDiscordAction({
action: "readMessages",
accountId: accountId ?? void 0,
channelId: resolveChannelId(),
limit,
before: readStringParam(params, "before"),
after: readStringParam(params, "after"),
around: readStringParam(params, "around")
}, cfg, actionOptions);
}
if (action === "edit") {
const messageId = readStringParam(params, "messageId", { required: true });
const content = readStringParam(params, "message", { required: true });
return await handleDiscordAction({
action: "editMessage",
accountId: accountId ?? void 0,
channelId: resolveChannelId(),
messageId,
content
}, cfg, actionOptions);
}
if (action === "delete") {
const messageId = readStringParam(params, "messageId", { required: true });
return await handleDiscordAction({
action: "deleteMessage",
accountId: accountId ?? void 0,
channelId: resolveChannelId(),
messageId
}, cfg, actionOptions);
}
if (action === "pin" || action === "unpin" || action === "list-pins") {
const messageId = action === "list-pins" ? void 0 : readStringParam(params, "messageId", { required: true });
return await handleDiscordAction({
action: action === "pin" ? "pinMessage" : action === "unpin" ? "unpinMessage" : "listPins",
accountId: accountId ?? void 0,
channelId: resolveChannelId(),
messageId
}, cfg, actionOptions);
}
if (action === "permissions") return await handleDiscordAction({
action: "permissions",
accountId: accountId ?? void 0,
channelId: resolveChannelId()
}, cfg, actionOptions);
if (action === "thread-create") {
const name = readStringParam(params, "threadName", { required: true });
const messageId = readStringParam(params, "messageId");
const content = readStringParam(params, "message");
const autoArchiveMinutes = readPositiveIntegerParam(params, "autoArchiveMin");
const appliedTags = readStringArrayParam(params, "appliedTags");
const result = await handleDiscordAction({
action: "threadCreate",
accountId: accountId ?? void 0,
channelId: resolveChannelId(),
name,
messageId,
content,
autoArchiveMinutes,
appliedTags: appliedTags ?? void 0
}, cfg, actionOptions);
notifyVisibleOutbound(resolveChannelId());
return result;
}
if (action === "sticker") {
const to = readStringParam(params, "to", { required: true });
const stickerIds = readStringArrayParam(params, "stickerId", {
required: true,
label: "sticker-id"
}) ?? [];
const result = await handleDiscordAction({
action: "sticker",
accountId: accountId ?? void 0,
to,
stickerIds,
content: readStringParam(params, "message")
}, cfg, actionOptions);
notifyVisibleOutbound(to);
return result;
}
if (action === "set-presence") return await handleDiscordAction({
action: "setPresence",
accountId: accountId ?? void 0,
status: readStringParam(params, "status"),
activityType: readStringParam(params, "activityType"),
activityName: readStringParam(params, "activityName"),
activityUrl: readStringParam(params, "activityUrl"),
activityState: readStringParam(params, "activityState")
}, cfg, actionOptions);
const adminResult = await tryHandleDiscordMessageActionGuildAdmin({
ctx,
resolveChannelId
});
if (adminResult !== void 0) {
if (action === "thread-reply") notifyVisibleOutbound(readStringParam(params, "threadId") ?? readTarget());
return adminResult;
}
throw new Error(`Action ${action} is not supported for provider ${providerId}.`);
}
//#endregion
export { handleDiscordMessageAction };