Files
openclaw/src/telegram/group-access.ts
Ayaan Zaidi b6a9741ba4 refactor(telegram): simplify send/dispatch/target handling (#17819)
Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: fcb7aeeca3
Co-authored-by: obviyus <22031114+obviyus@users.noreply.github.com>
Co-authored-by: obviyus <22031114+obviyus@users.noreply.github.com>
Reviewed-by: @obviyus
2026-02-16 14:00:34 +05:30

142 lines
4.6 KiB
TypeScript

import type { OpenClawConfig } from "../config/config.js";
import type { ChannelGroupPolicy } from "../config/group-policy.js";
import type {
TelegramAccountConfig,
TelegramGroupConfig,
TelegramTopicConfig,
} from "../config/types.js";
import { isSenderAllowed, type NormalizedAllowFrom } from "./bot-access.js";
import { firstDefined } from "./bot-access.js";
export type TelegramGroupBaseBlockReason =
| "group-disabled"
| "topic-disabled"
| "group-override-unauthorized";
export type TelegramGroupBaseAccessResult =
| { allowed: true }
| { allowed: false; reason: TelegramGroupBaseBlockReason };
export const evaluateTelegramGroupBaseAccess = (params: {
isGroup: boolean;
groupConfig?: TelegramGroupConfig;
topicConfig?: TelegramTopicConfig;
hasGroupAllowOverride: boolean;
effectiveGroupAllow: NormalizedAllowFrom;
senderId?: string;
senderUsername?: string;
enforceAllowOverride: boolean;
requireSenderForAllowOverride: boolean;
}): TelegramGroupBaseAccessResult => {
if (!params.isGroup) {
return { allowed: true };
}
if (params.groupConfig?.enabled === false) {
return { allowed: false, reason: "group-disabled" };
}
if (params.topicConfig?.enabled === false) {
return { allowed: false, reason: "topic-disabled" };
}
if (!params.enforceAllowOverride || !params.hasGroupAllowOverride) {
return { allowed: true };
}
const senderId = params.senderId ?? "";
if (params.requireSenderForAllowOverride && !senderId) {
return { allowed: false, reason: "group-override-unauthorized" };
}
const allowed = isSenderAllowed({
allow: params.effectiveGroupAllow,
senderId,
senderUsername: params.senderUsername ?? "",
});
if (!allowed) {
return { allowed: false, reason: "group-override-unauthorized" };
}
return { allowed: true };
};
export type TelegramGroupPolicyBlockReason =
| "group-policy-disabled"
| "group-policy-allowlist-no-sender"
| "group-policy-allowlist-empty"
| "group-policy-allowlist-unauthorized"
| "group-chat-not-allowed";
export type TelegramGroupPolicyAccessResult =
| { allowed: true; groupPolicy: "open" | "disabled" | "allowlist" }
| {
allowed: false;
reason: TelegramGroupPolicyBlockReason;
groupPolicy: "open" | "disabled" | "allowlist";
};
export const evaluateTelegramGroupPolicyAccess = (params: {
isGroup: boolean;
chatId: string | number;
cfg: OpenClawConfig;
telegramCfg: TelegramAccountConfig;
topicConfig?: TelegramTopicConfig;
groupConfig?: TelegramGroupConfig;
effectiveGroupAllow: NormalizedAllowFrom;
senderId?: string;
senderUsername?: string;
resolveGroupPolicy: (chatId: string | number) => ChannelGroupPolicy;
enforcePolicy: boolean;
useTopicAndGroupOverrides: boolean;
enforceAllowlistAuthorization: boolean;
allowEmptyAllowlistEntries: boolean;
requireSenderForAllowlistAuthorization: boolean;
checkChatAllowlist: boolean;
}): TelegramGroupPolicyAccessResult => {
const fallbackPolicy =
firstDefined(
params.telegramCfg.groupPolicy,
params.cfg.channels?.defaults?.groupPolicy,
"open",
) ?? "open";
const groupPolicy = params.useTopicAndGroupOverrides
? (firstDefined(
params.topicConfig?.groupPolicy,
params.groupConfig?.groupPolicy,
params.telegramCfg.groupPolicy,
params.cfg.channels?.defaults?.groupPolicy,
"open",
) ?? "open")
: fallbackPolicy;
if (!params.isGroup || !params.enforcePolicy) {
return { allowed: true, groupPolicy };
}
if (groupPolicy === "disabled") {
return { allowed: false, reason: "group-policy-disabled", groupPolicy };
}
if (groupPolicy === "allowlist" && params.enforceAllowlistAuthorization) {
const senderId = params.senderId ?? "";
if (params.requireSenderForAllowlistAuthorization && !senderId) {
return { allowed: false, reason: "group-policy-allowlist-no-sender", groupPolicy };
}
if (!params.allowEmptyAllowlistEntries && !params.effectiveGroupAllow.hasEntries) {
return { allowed: false, reason: "group-policy-allowlist-empty", groupPolicy };
}
const senderUsername = params.senderUsername ?? "";
if (
!isSenderAllowed({
allow: params.effectiveGroupAllow,
senderId,
senderUsername,
})
) {
return { allowed: false, reason: "group-policy-allowlist-unauthorized", groupPolicy };
}
}
if (params.checkChatAllowlist) {
const groupAllowlist = params.resolveGroupPolicy(params.chatId);
if (groupAllowlist.allowlistEnabled && !groupAllowlist.allowed) {
return { allowed: false, reason: "group-chat-not-allowed", groupPolicy };
}
}
return { allowed: true, groupPolicy };
};