refactor: require target for message actions

This commit is contained in:
Peter Steinberger
2026-01-17 04:06:14 +00:00
parent 87cecd0268
commit 6e4d86f426
38 changed files with 517 additions and 184 deletions

View File

@@ -10,7 +10,7 @@ const EXAMPLES = [
"Link personal WhatsApp Web and show QR + connection logs.",
],
[
'clawdbot message send --to +15555550123 --message "Hi" --json',
'clawdbot message send --target +15555550123 --message "Hi" --json',
"Send via your web session and print JSON result.",
],
["clawdbot gateway --port 18789", "Run the WebSocket Gateway locally."],
@@ -22,7 +22,7 @@ const EXAMPLES = [
"Talk directly to the agent using the Gateway; optionally send the WhatsApp reply.",
],
[
'clawdbot message send --channel telegram --to @mychat --message "Hi"',
'clawdbot message send --channel telegram --target @mychat --message "Hi"',
"Send via your Telegram bot.",
],
] as const;

View File

@@ -25,9 +25,9 @@ export function createMessageCliHelpers(
.option("--verbose", "Verbose logging", false);
const withMessageTarget = (command: Command) =>
command.option("-t, --to <dest>", CHANNEL_TARGET_DESCRIPTION);
command.option("-t, --target <dest>", CHANNEL_TARGET_DESCRIPTION);
const withRequiredMessageTarget = (command: Command) =>
command.requiredOption("-t, --to <dest>", CHANNEL_TARGET_DESCRIPTION);
command.requiredOption("-t, --target <dest>", CHANNEL_TARGET_DESCRIPTION);
const runMessageAction = async (action: string, opts: Record<string, unknown>) => {
setVerbose(Boolean(opts.verbose));

View File

@@ -40,10 +40,9 @@ export function registerMessageDiscordAdminCommands(message: Command, helpers: M
const channel = message.command("channel").description("Channel actions");
helpers
.withMessageBase(
channel
.command("info")
.description("Fetch channel info")
.requiredOption("--channel-id <id>", "Channel id"),
helpers.withRequiredMessageTarget(
channel.command("info").description("Fetch channel info"),
),
)
.action(async (opts) => {
await helpers.runMessageAction("channel-info", opts);

View File

@@ -5,11 +5,10 @@ import type { MessageCliHelpers } from "./helpers.js";
export function registerMessagePermissionsCommand(message: Command, helpers: MessageCliHelpers) {
helpers
.withMessageBase(
helpers.withMessageTarget(
helpers.withRequiredMessageTarget(
message.command("permissions").description("Fetch channel permissions"),
),
)
.option("--channel-id <id>", "Channel id (defaults to --to)")
.action(async (opts) => {
await helpers.runMessageAction("permissions", opts);
});

View File

@@ -2,15 +2,10 @@ import type { Command } from "commander";
import type { MessageCliHelpers } from "./helpers.js";
export function registerMessagePinCommands(message: Command, helpers: MessageCliHelpers) {
const withPinsTarget = (command: Command) =>
command.option("--channel-id <id>", "Channel id (defaults to --to; required for WhatsApp)");
const pins = [
helpers
.withMessageBase(
withPinsTarget(
helpers.withMessageTarget(message.command("pin").description("Pin a message")),
),
helpers.withRequiredMessageTarget(message.command("pin").description("Pin a message")),
)
.requiredOption("--message-id <id>", "Message id")
.action(async (opts) => {
@@ -18,9 +13,7 @@ export function registerMessagePinCommands(message: Command, helpers: MessageCli
}),
helpers
.withMessageBase(
withPinsTarget(
helpers.withMessageTarget(message.command("unpin").description("Unpin a message")),
),
helpers.withRequiredMessageTarget(message.command("unpin").description("Unpin a message")),
)
.requiredOption("--message-id <id>", "Message id")
.action(async (opts) => {
@@ -28,9 +21,8 @@ export function registerMessagePinCommands(message: Command, helpers: MessageCli
}),
helpers
.withMessageBase(
helpers.withMessageTarget(message.command("pins").description("List pinned messages")),
helpers.withRequiredMessageTarget(message.command("pins").description("List pinned messages")),
)
.option("--channel-id <id>", "Channel id (defaults to --to)")
.option("--limit <n>", "Result limit")
.action(async (opts) => {
await helpers.runMessageAction("list-pins", opts);

View File

@@ -4,27 +4,27 @@ import type { MessageCliHelpers } from "./helpers.js";
export function registerMessageReactionsCommands(message: Command, helpers: MessageCliHelpers) {
helpers
.withMessageBase(
helpers.withMessageTarget(message.command("react").description("Add or remove a reaction")),
helpers.withRequiredMessageTarget(
message.command("react").description("Add or remove a reaction"),
),
)
.requiredOption("--message-id <id>", "Message id")
.option("--emoji <emoji>", "Emoji for reactions")
.option("--remove", "Remove reaction", false)
.option("--participant <id>", "WhatsApp reaction participant")
.option("--from-me", "WhatsApp reaction fromMe", false)
.option("--channel-id <id>", "Channel id (defaults to --to)")
.action(async (opts) => {
await helpers.runMessageAction("react", opts);
});
helpers
.withMessageBase(
helpers.withMessageTarget(
helpers.withRequiredMessageTarget(
message.command("reactions").description("List reactions on a message"),
),
)
.requiredOption("--message-id <id>", "Message id")
.option("--limit <n>", "Result limit")
.option("--channel-id <id>", "Channel id (defaults to --to)")
.action(async (opts) => {
await helpers.runMessageAction("reactions", opts);
});

View File

@@ -7,13 +7,12 @@ export function registerMessageReadEditDeleteCommands(
) {
helpers
.withMessageBase(
helpers.withMessageTarget(message.command("read").description("Read recent messages")),
helpers.withRequiredMessageTarget(message.command("read").description("Read recent messages")),
)
.option("--limit <n>", "Result limit")
.option("--before <id>", "Read/search before id")
.option("--after <id>", "Read/search after id")
.option("--around <id>", "Read around id")
.option("--channel-id <id>", "Channel id (defaults to --to)")
.option("--include-thread", "Include thread replies (Discord)", false)
.action(async (opts) => {
await helpers.runMessageAction("read", opts);
@@ -21,7 +20,7 @@ export function registerMessageReadEditDeleteCommands(
helpers
.withMessageBase(
helpers.withMessageTarget(
helpers.withRequiredMessageTarget(
message
.command("edit")
.description("Edit a message")
@@ -29,7 +28,6 @@ export function registerMessageReadEditDeleteCommands(
.requiredOption("-m, --message <text>", "Message body"),
),
)
.option("--channel-id <id>", "Channel id (defaults to --to)")
.option("--thread-id <id>", "Thread id (Telegram forum thread)")
.action(async (opts) => {
await helpers.runMessageAction("edit", opts);
@@ -37,14 +35,13 @@ export function registerMessageReadEditDeleteCommands(
helpers
.withMessageBase(
helpers.withMessageTarget(
helpers.withRequiredMessageTarget(
message
.command("delete")
.description("Delete a message")
.requiredOption("--message-id <id>", "Message id"),
),
)
.option("--channel-id <id>", "Channel id (defaults to --to)")
.action(async (opts) => {
await helpers.runMessageAction("delete", opts);
});

View File

@@ -6,14 +6,13 @@ export function registerMessageThreadCommands(message: Command, helpers: Message
helpers
.withMessageBase(
helpers.withMessageTarget(
helpers.withRequiredMessageTarget(
thread
.command("create")
.description("Create a thread")
.requiredOption("--thread-name <name>", "Thread name"),
),
)
.option("--channel-id <id>", "Channel id (defaults to --to)")
.option("--message-id <id>", "Message id (optional)")
.option("--auto-archive-min <n>", "Thread auto-archive minutes")
.action(async (opts) => {

View File

@@ -29,10 +29,10 @@ export function registerMessageCommands(program: Command, ctx: ProgramContext) {
() =>
`
Examples:
clawdbot message send --to +15555550123 --message "Hi"
clawdbot message send --to +15555550123 --message "Hi" --media photo.jpg
clawdbot message poll --channel discord --to channel:123 --poll-question "Snack?" --poll-option Pizza --poll-option Sushi
clawdbot message react --channel discord --to 123 --message-id 456 --emoji "✅"
clawdbot message send --target +15555550123 --message "Hi"
clawdbot message send --target +15555550123 --message "Hi" --media photo.jpg
clawdbot message poll --channel discord --target channel:123 --poll-question "Snack?" --poll-option Pizza --poll-option Sushi
clawdbot message react --channel discord --target 123 --message-id 456 --emoji "✅"
${theme.muted("Docs:")} ${formatDocsLink("/cli/message", "docs.clawd.bot/cli/message")}`,
)