178 lines
4.2 KiB
TypeScript
178 lines
4.2 KiB
TypeScript
import type { CliDeps } from "../cli/deps.js";
|
|
import { loadConfig } from "../config/config.js";
|
|
import { callGateway, randomIdempotencyKey } from "../gateway/call.js";
|
|
import { success } from "../globals.js";
|
|
import type { RuntimeEnv } from "../runtime.js";
|
|
import { resolveTelegramToken } from "../telegram/token.js";
|
|
|
|
export async function sendCommand(
|
|
opts: {
|
|
to: string;
|
|
message: string;
|
|
provider?: string;
|
|
json?: boolean;
|
|
dryRun?: boolean;
|
|
media?: string;
|
|
},
|
|
deps: CliDeps,
|
|
runtime: RuntimeEnv,
|
|
) {
|
|
const provider = (opts.provider ?? "whatsapp").toLowerCase();
|
|
|
|
if (opts.dryRun) {
|
|
runtime.log(
|
|
`[dry-run] would send via ${provider} -> ${opts.to}: ${opts.message}${opts.media ? ` (media ${opts.media})` : ""}`,
|
|
);
|
|
return;
|
|
}
|
|
|
|
if (provider === "telegram") {
|
|
const { token } = resolveTelegramToken(loadConfig());
|
|
const result = await deps.sendMessageTelegram(opts.to, opts.message, {
|
|
token: token || undefined,
|
|
mediaUrl: opts.media,
|
|
});
|
|
runtime.log(
|
|
success(
|
|
`✅ Sent via telegram. Message ID: ${result.messageId} (chat ${result.chatId})`,
|
|
),
|
|
);
|
|
if (opts.json) {
|
|
runtime.log(
|
|
JSON.stringify(
|
|
{
|
|
provider: "telegram",
|
|
via: "direct",
|
|
to: opts.to,
|
|
chatId: result.chatId,
|
|
messageId: result.messageId,
|
|
mediaUrl: opts.media ?? null,
|
|
},
|
|
null,
|
|
2,
|
|
),
|
|
);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (provider === "discord") {
|
|
const result = await deps.sendMessageDiscord(opts.to, opts.message, {
|
|
token: process.env.DISCORD_BOT_TOKEN,
|
|
mediaUrl: opts.media,
|
|
});
|
|
runtime.log(
|
|
success(
|
|
`✅ Sent via discord. Message ID: ${result.messageId} (channel ${result.channelId})`,
|
|
),
|
|
);
|
|
if (opts.json) {
|
|
runtime.log(
|
|
JSON.stringify(
|
|
{
|
|
provider: "discord",
|
|
via: "direct",
|
|
to: opts.to,
|
|
channelId: result.channelId,
|
|
messageId: result.messageId,
|
|
mediaUrl: opts.media ?? null,
|
|
},
|
|
null,
|
|
2,
|
|
),
|
|
);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (provider === "signal") {
|
|
const result = await deps.sendMessageSignal(opts.to, opts.message, {
|
|
mediaUrl: opts.media,
|
|
});
|
|
runtime.log(success(`✅ Sent via signal. Message ID: ${result.messageId}`));
|
|
if (opts.json) {
|
|
runtime.log(
|
|
JSON.stringify(
|
|
{
|
|
provider: "signal",
|
|
via: "direct",
|
|
to: opts.to,
|
|
messageId: result.messageId,
|
|
mediaUrl: opts.media ?? null,
|
|
},
|
|
null,
|
|
2,
|
|
),
|
|
);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (provider === "imessage" || provider === "imsg") {
|
|
const result = await deps.sendMessageIMessage(opts.to, opts.message, {
|
|
mediaUrl: opts.media,
|
|
});
|
|
runtime.log(
|
|
success(`✅ Sent via iMessage. Message ID: ${result.messageId}`),
|
|
);
|
|
if (opts.json) {
|
|
runtime.log(
|
|
JSON.stringify(
|
|
{
|
|
provider: "imessage",
|
|
via: "direct",
|
|
to: opts.to,
|
|
messageId: result.messageId,
|
|
mediaUrl: opts.media ?? null,
|
|
},
|
|
null,
|
|
2,
|
|
),
|
|
);
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Always send via gateway over WS to avoid multi-session corruption.
|
|
const sendViaGateway = async () =>
|
|
callGateway<{
|
|
messageId: string;
|
|
}>({
|
|
url: "ws://127.0.0.1:18789",
|
|
method: "send",
|
|
params: {
|
|
to: opts.to,
|
|
message: opts.message,
|
|
mediaUrl: opts.media,
|
|
provider,
|
|
idempotencyKey: randomIdempotencyKey(),
|
|
},
|
|
timeoutMs: 10_000,
|
|
clientName: "cli",
|
|
mode: "cli",
|
|
});
|
|
|
|
const result = await sendViaGateway();
|
|
|
|
runtime.log(
|
|
success(
|
|
`✅ Sent via gateway. Message ID: ${result.messageId ?? "unknown"}`,
|
|
),
|
|
);
|
|
if (opts.json) {
|
|
runtime.log(
|
|
JSON.stringify(
|
|
{
|
|
provider: "web",
|
|
via: "gateway",
|
|
to: opts.to,
|
|
messageId: result.messageId,
|
|
mediaUrl: opts.media ?? null,
|
|
},
|
|
null,
|
|
2,
|
|
),
|
|
);
|
|
}
|
|
}
|