mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 07:40:44 +00:00
refactor: move telegram poll visibility out of core
This commit is contained in:
13
extensions/telegram/src/poll-visibility.test.ts
Normal file
13
extensions/telegram/src/poll-visibility.test.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { resolveTelegramPollVisibility } from "./poll-visibility.js";
|
||||
|
||||
describe("telegram poll visibility", () => {
|
||||
it("resolves poll visibility aliases", () => {
|
||||
expect(resolveTelegramPollVisibility({ pollAnonymous: true })).toBe(true);
|
||||
expect(resolveTelegramPollVisibility({ pollPublic: true })).toBe(false);
|
||||
expect(resolveTelegramPollVisibility({})).toBeUndefined();
|
||||
expect(() => resolveTelegramPollVisibility({ pollAnonymous: true, pollPublic: true })).toThrow(
|
||||
/mutually exclusive/i,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { hasPollCreationParams, resolveTelegramPollVisibility } from "./poll-params.js";
|
||||
import { hasPollCreationParams } from "./poll-params.js";
|
||||
|
||||
describe("poll params", () => {
|
||||
it("does not treat explicit false booleans as poll creation params", () => {
|
||||
@@ -60,12 +60,9 @@ describe("poll params", () => {
|
||||
expect(hasPollCreationParams({ poll_public: "true" })).toBe(true);
|
||||
});
|
||||
|
||||
it("resolves telegram poll visibility flags", () => {
|
||||
expect(resolveTelegramPollVisibility({ pollAnonymous: true })).toBe(true);
|
||||
expect(resolveTelegramPollVisibility({ pollPublic: true })).toBe(false);
|
||||
expect(resolveTelegramPollVisibility({})).toBeUndefined();
|
||||
expect(() => resolveTelegramPollVisibility({ pollAnonymous: true, pollPublic: true })).toThrow(
|
||||
/mutually exclusive/i,
|
||||
);
|
||||
it("ignores poll vote params when deciding whether send should become poll", () => {
|
||||
expect(hasPollCreationParams({ pollId: "poll-1" })).toBe(false);
|
||||
expect(hasPollCreationParams({ pollOptionId: "answer-1" })).toBe(false);
|
||||
expect(hasPollCreationParams({ pollOptionIndexes: [1] })).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,40 +14,67 @@ const SHARED_POLL_CREATION_PARAM_DEFS = {
|
||||
pollMulti: { kind: "boolean" },
|
||||
} satisfies Record<string, PollCreationParamDef>;
|
||||
|
||||
const TELEGRAM_POLL_CREATION_PARAM_DEFS = {
|
||||
pollDurationSeconds: { kind: "number" },
|
||||
pollAnonymous: { kind: "boolean" },
|
||||
pollPublic: { kind: "boolean" },
|
||||
} satisfies Record<string, PollCreationParamDef>;
|
||||
|
||||
export const POLL_CREATION_PARAM_DEFS: Record<string, PollCreationParamDef> = {
|
||||
...SHARED_POLL_CREATION_PARAM_DEFS,
|
||||
...TELEGRAM_POLL_CREATION_PARAM_DEFS,
|
||||
};
|
||||
export const POLL_CREATION_PARAM_DEFS: Record<string, PollCreationParamDef> =
|
||||
SHARED_POLL_CREATION_PARAM_DEFS;
|
||||
|
||||
type SharedPollCreationParamName = keyof typeof SHARED_POLL_CREATION_PARAM_DEFS;
|
||||
|
||||
const POLL_CREATION_PARAM_NAMES = Object.keys(POLL_CREATION_PARAM_DEFS);
|
||||
export const SHARED_POLL_CREATION_PARAM_NAMES = Object.keys(
|
||||
SHARED_POLL_CREATION_PARAM_DEFS,
|
||||
) as SharedPollCreationParamName[];
|
||||
const SHARED_POLL_CREATION_PARAM_KEY_SET = new Set(
|
||||
SHARED_POLL_CREATION_PARAM_NAMES.map(normalizePollParamKey),
|
||||
);
|
||||
const POLL_VOTE_PARAM_KEY_SET = new Set(
|
||||
["pollId", "pollOptionId", "pollOptionIds", "pollOptionIndex", "pollOptionIndexes"].map(
|
||||
normalizePollParamKey,
|
||||
),
|
||||
);
|
||||
|
||||
function readPollParamRaw(params: Record<string, unknown>, key: string): unknown {
|
||||
return readSnakeCaseParamRaw(params, key);
|
||||
}
|
||||
|
||||
export function resolveTelegramPollVisibility(params: {
|
||||
pollAnonymous?: boolean;
|
||||
pollPublic?: boolean;
|
||||
}): boolean | undefined {
|
||||
if (params.pollAnonymous && params.pollPublic) {
|
||||
throw new Error("pollAnonymous and pollPublic are mutually exclusive");
|
||||
function normalizePollParamKey(key: string): string {
|
||||
return normalizeLowercaseStringOrEmpty(key.replaceAll("_", ""));
|
||||
}
|
||||
|
||||
function isChannelPollCreationParamName(key: string): boolean {
|
||||
const normalized = normalizePollParamKey(key);
|
||||
return (
|
||||
normalized.startsWith("poll") &&
|
||||
!SHARED_POLL_CREATION_PARAM_KEY_SET.has(normalized) &&
|
||||
!POLL_VOTE_PARAM_KEY_SET.has(normalized)
|
||||
);
|
||||
}
|
||||
|
||||
function hasExplicitUnknownPollValue(key: string, value: unknown): boolean {
|
||||
if (value === true) {
|
||||
return true;
|
||||
}
|
||||
return params.pollAnonymous ? true : params.pollPublic ? false : undefined;
|
||||
if (typeof value === "number") {
|
||||
return Number.isFinite(value) && value !== 0;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
const trimmed = value.trim();
|
||||
if (trimmed.length === 0) {
|
||||
return false;
|
||||
}
|
||||
if (normalizePollParamKey(key).includes("duration")) {
|
||||
const parsed = Number(trimmed);
|
||||
return Number.isFinite(parsed) && parsed !== 0;
|
||||
}
|
||||
const normalized = normalizeLowercaseStringOrEmpty(trimmed);
|
||||
return normalized !== "false" && normalized !== "0";
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
return value.some((entry) => hasExplicitUnknownPollValue(key, entry));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function hasPollCreationParams(params: Record<string, unknown>): boolean {
|
||||
for (const key of POLL_CREATION_PARAM_NAMES) {
|
||||
for (const key of SHARED_POLL_CREATION_PARAM_NAMES) {
|
||||
const def = POLL_CREATION_PARAM_DEFS[key];
|
||||
const value = readPollParamRaw(params, key);
|
||||
if (def.kind === "string" && typeof value === "string" && value.trim().length > 0) {
|
||||
@@ -88,5 +115,10 @@ export function hasPollCreationParams(params: Record<string, unknown>): boolean
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const [key, value] of Object.entries(params)) {
|
||||
if (isChannelPollCreationParamName(key) && hasExplicitUnknownPollValue(key, value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user