fix: add groupContextFromAll config for backward compat
- groupContextFromAll: boolean (default: false) - opt-in flag - When enabled, group messages from senders not in groupAllowFrom are stored as pending context instead of being dropped - Available at both top-level whatsapp config and per-account level - Added to types, zod schema, resolved account, and access control - Default false preserves existing behavior
This commit is contained in:
parent
85cc968aab
commit
ed87b1dd91
@ -47,6 +47,12 @@ export type WhatsAppConfig = {
|
|||||||
* - "allowlist": only allow group messages from senders in groupAllowFrom/allowFrom
|
* - "allowlist": only allow group messages from senders in groupAllowFrom/allowFrom
|
||||||
*/
|
*/
|
||||||
groupPolicy?: GroupPolicy;
|
groupPolicy?: GroupPolicy;
|
||||||
|
/**
|
||||||
|
* When true, messages from group members not in groupAllowFrom are still
|
||||||
|
* stored as pending context (visible in "[Chat messages since your last reply]")
|
||||||
|
* even though they cannot trigger a reply. Default: false (old behavior: drop entirely).
|
||||||
|
*/
|
||||||
|
groupContextFromAll?: boolean;
|
||||||
/** Max group messages to keep as history context (0 disables). */
|
/** Max group messages to keep as history context (0 disables). */
|
||||||
historyLimit?: number;
|
historyLimit?: number;
|
||||||
/** Max DM turns to keep as history context. */
|
/** Max DM turns to keep as history context. */
|
||||||
@ -118,6 +124,8 @@ export type WhatsAppAccountConfig = {
|
|||||||
allowFrom?: string[];
|
allowFrom?: string[];
|
||||||
groupAllowFrom?: string[];
|
groupAllowFrom?: string[];
|
||||||
groupPolicy?: GroupPolicy;
|
groupPolicy?: GroupPolicy;
|
||||||
|
/** Store context from non-allowlisted group senders (default: false). */
|
||||||
|
groupContextFromAll?: boolean;
|
||||||
/** Max group messages to keep as history context (0 disables). */
|
/** Max group messages to keep as history context (0 disables). */
|
||||||
historyLimit?: number;
|
historyLimit?: number;
|
||||||
/** Max DM turns to keep as history context. */
|
/** Max DM turns to keep as history context. */
|
||||||
|
|||||||
@ -28,6 +28,7 @@ export const WhatsAppAccountSchema = z
|
|||||||
allowFrom: z.array(z.string()).optional(),
|
allowFrom: z.array(z.string()).optional(),
|
||||||
groupAllowFrom: z.array(z.string()).optional(),
|
groupAllowFrom: z.array(z.string()).optional(),
|
||||||
groupPolicy: GroupPolicySchema.optional().default("allowlist"),
|
groupPolicy: GroupPolicySchema.optional().default("allowlist"),
|
||||||
|
groupContextFromAll: z.boolean().optional().default(false),
|
||||||
historyLimit: z.number().int().min(0).optional(),
|
historyLimit: z.number().int().min(0).optional(),
|
||||||
dmHistoryLimit: z.number().int().min(0).optional(),
|
dmHistoryLimit: z.number().int().min(0).optional(),
|
||||||
dms: z.record(z.string(), DmConfigSchema.optional()).optional(),
|
dms: z.record(z.string(), DmConfigSchema.optional()).optional(),
|
||||||
@ -85,6 +86,7 @@ export const WhatsAppConfigSchema = z
|
|||||||
allowFrom: z.array(z.string()).optional(),
|
allowFrom: z.array(z.string()).optional(),
|
||||||
groupAllowFrom: z.array(z.string()).optional(),
|
groupAllowFrom: z.array(z.string()).optional(),
|
||||||
groupPolicy: GroupPolicySchema.optional().default("allowlist"),
|
groupPolicy: GroupPolicySchema.optional().default("allowlist"),
|
||||||
|
groupContextFromAll: z.boolean().optional().default(false),
|
||||||
historyLimit: z.number().int().min(0).optional(),
|
historyLimit: z.number().int().min(0).optional(),
|
||||||
dmHistoryLimit: z.number().int().min(0).optional(),
|
dmHistoryLimit: z.number().int().min(0).optional(),
|
||||||
dms: z.record(z.string(), DmConfigSchema.optional()).optional(),
|
dms: z.record(z.string(), DmConfigSchema.optional()).optional(),
|
||||||
|
|||||||
@ -20,6 +20,7 @@ export type ResolvedWhatsAppAccount = {
|
|||||||
allowFrom?: string[];
|
allowFrom?: string[];
|
||||||
groupAllowFrom?: string[];
|
groupAllowFrom?: string[];
|
||||||
groupPolicy?: GroupPolicy;
|
groupPolicy?: GroupPolicy;
|
||||||
|
groupContextFromAll?: boolean;
|
||||||
dmPolicy?: DmPolicy;
|
dmPolicy?: DmPolicy;
|
||||||
textChunkLimit?: number;
|
textChunkLimit?: number;
|
||||||
chunkMode?: "length" | "newline";
|
chunkMode?: "length" | "newline";
|
||||||
@ -150,6 +151,7 @@ export function resolveWhatsAppAccount(params: {
|
|||||||
allowFrom: accountCfg?.allowFrom ?? rootCfg?.allowFrom,
|
allowFrom: accountCfg?.allowFrom ?? rootCfg?.allowFrom,
|
||||||
groupAllowFrom: accountCfg?.groupAllowFrom ?? rootCfg?.groupAllowFrom,
|
groupAllowFrom: accountCfg?.groupAllowFrom ?? rootCfg?.groupAllowFrom,
|
||||||
groupPolicy: accountCfg?.groupPolicy ?? rootCfg?.groupPolicy,
|
groupPolicy: accountCfg?.groupPolicy ?? rootCfg?.groupPolicy,
|
||||||
|
groupContextFromAll: accountCfg?.groupContextFromAll ?? rootCfg?.groupContextFromAll,
|
||||||
textChunkLimit: accountCfg?.textChunkLimit ?? rootCfg?.textChunkLimit,
|
textChunkLimit: accountCfg?.textChunkLimit ?? rootCfg?.textChunkLimit,
|
||||||
chunkMode: accountCfg?.chunkMode ?? rootCfg?.chunkMode,
|
chunkMode: accountCfg?.chunkMode ?? rootCfg?.chunkMode,
|
||||||
mediaMaxMb: accountCfg?.mediaMaxMb ?? rootCfg?.mediaMaxMb,
|
mediaMaxMb: accountCfg?.mediaMaxMb ?? rootCfg?.mediaMaxMb,
|
||||||
|
|||||||
@ -53,6 +53,8 @@ export async function checkInboundAccessControl(params: {
|
|||||||
const groupAllowFrom =
|
const groupAllowFrom =
|
||||||
account.groupAllowFrom ??
|
account.groupAllowFrom ??
|
||||||
(configuredAllowFrom && configuredAllowFrom.length > 0 ? configuredAllowFrom : undefined);
|
(configuredAllowFrom && configuredAllowFrom.length > 0 ? configuredAllowFrom : undefined);
|
||||||
|
const groupContextFromAll =
|
||||||
|
account.groupContextFromAll ?? cfg.channels?.whatsapp?.groupContextFromAll ?? false;
|
||||||
const isSamePhone = params.from === params.selfE164;
|
const isSamePhone = params.from === params.selfE164;
|
||||||
const isSelfChat = isSelfChatMode(params.selfE164, configuredAllowFrom);
|
const isSelfChat = isSelfChatMode(params.selfE164, configuredAllowFrom);
|
||||||
const pairingGraceMs =
|
const pairingGraceMs =
|
||||||
@ -107,6 +109,7 @@ export async function checkInboundAccessControl(params: {
|
|||||||
groupHasWildcard ||
|
groupHasWildcard ||
|
||||||
(params.senderE164 != null && normalizedGroupAllowFrom.includes(params.senderE164));
|
(params.senderE164 != null && normalizedGroupAllowFrom.includes(params.senderE164));
|
||||||
if (!senderAllowed) {
|
if (!senderAllowed) {
|
||||||
|
if (groupContextFromAll) {
|
||||||
logVerbose(
|
logVerbose(
|
||||||
`Group message from ${params.senderE164 ?? "unknown sender"} not in groupAllowFrom (storing for context)`,
|
`Group message from ${params.senderE164 ?? "unknown sender"} not in groupAllowFrom (storing for context)`,
|
||||||
);
|
);
|
||||||
@ -118,6 +121,17 @@ export async function checkInboundAccessControl(params: {
|
|||||||
resolvedAccountId: account.accountId,
|
resolvedAccountId: account.accountId,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
logVerbose(
|
||||||
|
`Blocked group message from ${params.senderE164 ?? "unknown sender"} (groupPolicy: allowlist)`,
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
allowed: false,
|
||||||
|
storeForContext: false,
|
||||||
|
shouldMarkRead: false,
|
||||||
|
isSelfChat,
|
||||||
|
resolvedAccountId: account.accountId,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DM access control (secure defaults): "pairing" (default) / "allowlist" / "open" / "disabled".
|
// DM access control (secure defaults): "pairing" (default) / "allowlist" / "open" / "disabled".
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user