feat(commands): unify chat commands (#275)
* Chat commands: registry, access groups, Carbon * Chat commands: clear native commands on disable * fix(commands): align command surface typing * docs(changelog): note commands registry (PR #275) --------- Co-authored-by: Peter Steinberger <steipete@gmail.com>
This commit is contained in:
@@ -27,6 +27,7 @@ import { normalizeE164 } from "../../utils.js";
|
||||
import { resolveHeartbeatSeconds } from "../../web/reconnect.js";
|
||||
import { getWebAuthAgeMs, webAuthExists } from "../../web/session.js";
|
||||
import { resolveCommandAuthorization } from "../command-auth.js";
|
||||
import { shouldHandleTextCommands } from "../commands-registry.js";
|
||||
import {
|
||||
normalizeGroupActivation,
|
||||
parseActivationCommand,
|
||||
@@ -47,6 +48,7 @@ import { stripMentions, stripStructuralPrefixes } from "./mentions.js";
|
||||
import { incrementCompactionCount } from "./session-updates.js";
|
||||
|
||||
export type CommandContext = {
|
||||
surface: string;
|
||||
provider: string;
|
||||
isWhatsAppProvider: boolean;
|
||||
ownerList: string[];
|
||||
@@ -123,7 +125,8 @@ export function buildCommandContext(params: {
|
||||
cfg,
|
||||
commandAuthorized: params.commandAuthorized,
|
||||
});
|
||||
const provider = (ctx.Provider ?? "").trim().toLowerCase();
|
||||
const surface = (ctx.Surface ?? ctx.Provider ?? "").trim().toLowerCase();
|
||||
const provider = (ctx.Provider ?? surface).trim().toLowerCase();
|
||||
const abortKey =
|
||||
sessionKey ?? (auth.from || undefined) ?? (auth.to || undefined);
|
||||
const rawBodyNormalized = triggerBodyNormalized;
|
||||
@@ -132,6 +135,7 @@ export function buildCommandContext(params: {
|
||||
: rawBodyNormalized;
|
||||
|
||||
return {
|
||||
surface,
|
||||
provider,
|
||||
isWhatsAppProvider: auth.isWhatsAppProvider,
|
||||
ownerList: auth.ownerList,
|
||||
@@ -207,8 +211,13 @@ export async function handleCommands(params: {
|
||||
const sendPolicyCommand = parseSendPolicyCommand(
|
||||
command.commandBodyNormalized,
|
||||
);
|
||||
const allowTextCommands = shouldHandleTextCommands({
|
||||
cfg,
|
||||
surface: command.surface,
|
||||
commandSource: ctx.CommandSource,
|
||||
});
|
||||
|
||||
if (activationCommand.hasCommand) {
|
||||
if (allowTextCommands && activationCommand.hasCommand) {
|
||||
if (!isGroup) {
|
||||
return {
|
||||
shouldContinue: false,
|
||||
@@ -255,7 +264,7 @@ export async function handleCommands(params: {
|
||||
};
|
||||
}
|
||||
|
||||
if (sendPolicyCommand.hasCommand) {
|
||||
if (allowTextCommands && sendPolicyCommand.hasCommand) {
|
||||
if (!command.isAuthorizedSender) {
|
||||
logVerbose(
|
||||
`Ignoring /send from unauthorized sender: ${command.senderE164 || "<unknown>"}`,
|
||||
@@ -292,10 +301,7 @@ export async function handleCommands(params: {
|
||||
};
|
||||
}
|
||||
|
||||
if (
|
||||
command.commandBodyNormalized === "/restart" ||
|
||||
command.commandBodyNormalized.startsWith("/restart ")
|
||||
) {
|
||||
if (allowTextCommands && command.commandBodyNormalized === "/restart") {
|
||||
if (!command.isAuthorizedSender) {
|
||||
logVerbose(
|
||||
`Ignoring /restart from unauthorized sender: ${command.senderE164 || "<unknown>"}`,
|
||||
@@ -311,10 +317,8 @@ export async function handleCommands(params: {
|
||||
};
|
||||
}
|
||||
|
||||
const helpRequested =
|
||||
command.commandBodyNormalized === "/help" ||
|
||||
/(?:^|\s)\/help(?=$|\s|:)\b/i.test(command.commandBodyNormalized);
|
||||
if (helpRequested) {
|
||||
const helpRequested = command.commandBodyNormalized === "/help";
|
||||
if (allowTextCommands && helpRequested) {
|
||||
if (!command.isAuthorizedSender) {
|
||||
logVerbose(
|
||||
`Ignoring /help from unauthorized sender: ${command.senderE164 || "<unknown>"}`,
|
||||
@@ -326,9 +330,8 @@ export async function handleCommands(params: {
|
||||
|
||||
const statusRequested =
|
||||
directives.hasStatusDirective ||
|
||||
command.commandBodyNormalized === "/status" ||
|
||||
command.commandBodyNormalized.startsWith("/status ");
|
||||
if (statusRequested) {
|
||||
command.commandBodyNormalized === "/status";
|
||||
if (allowTextCommands && statusRequested) {
|
||||
if (!command.isAuthorizedSender) {
|
||||
logVerbose(
|
||||
`Ignoring /status from unauthorized sender: ${command.senderE164 || "<unknown>"}`,
|
||||
@@ -451,7 +454,7 @@ export async function handleCommands(params: {
|
||||
}
|
||||
|
||||
const abortRequested = isAbortTrigger(command.rawBodyNormalized);
|
||||
if (abortRequested) {
|
||||
if (allowTextCommands && abortRequested) {
|
||||
if (sessionEntry && sessionStore && sessionKey) {
|
||||
sessionEntry.abortedLastRun = true;
|
||||
sessionEntry.updatedAt = Date.now();
|
||||
|
||||
Reference in New Issue
Block a user