mirror of
https://github.com/moltbot/moltbot.git
synced 2026-04-27 00:17:29 +00:00
feat(telegram): add topic-edit action
This commit is contained in:
@@ -115,6 +115,9 @@ export const telegramMessageActions: ChannelMessageActionAdapter = {
|
||||
if (isEnabled("createForumTopic")) {
|
||||
actions.add("topic-create");
|
||||
}
|
||||
if (isEnabled("editForumTopic")) {
|
||||
actions.add("topic-edit");
|
||||
}
|
||||
return Array.from(actions);
|
||||
},
|
||||
supportsButtons: ({ cfg }) => {
|
||||
@@ -290,6 +293,30 @@ export const telegramMessageActions: ChannelMessageActionAdapter = {
|
||||
);
|
||||
}
|
||||
|
||||
if (action === "topic-edit") {
|
||||
const chatId = readTelegramChatIdParam(params);
|
||||
const messageThreadId =
|
||||
readNumberParam(params, "messageThreadId", { integer: true }) ??
|
||||
readNumberParam(params, "threadId", { integer: true });
|
||||
if (typeof messageThreadId !== "number") {
|
||||
throw new Error("messageThreadId or threadId is required.");
|
||||
}
|
||||
const name = readStringParam(params, "name");
|
||||
const iconCustomEmojiId = readStringParam(params, "iconCustomEmojiId");
|
||||
return await handleTelegramAction(
|
||||
{
|
||||
action: "editForumTopic",
|
||||
chatId,
|
||||
messageThreadId,
|
||||
name: name ?? undefined,
|
||||
iconCustomEmojiId: iconCustomEmojiId ?? undefined,
|
||||
accountId: accountId ?? undefined,
|
||||
},
|
||||
cfg,
|
||||
{ mediaLocalRoots },
|
||||
);
|
||||
}
|
||||
|
||||
throw new Error(`Action ${action} is not supported for provider ${providerId}.`);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -15,6 +15,7 @@ const { botApi, botCtorSpy, loadConfig, loadWebMedia, maybePersistResolvedTelegr
|
||||
const {
|
||||
buildInlineKeyboard,
|
||||
createForumTopicTelegram,
|
||||
editForumTopicTelegram,
|
||||
editMessageTelegram,
|
||||
pinMessageTelegram,
|
||||
reactMessageTelegram,
|
||||
@@ -257,6 +258,42 @@ describe("sendMessageTelegram", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("edits a Telegram forum topic name and icon via the shared helper", async () => {
|
||||
loadConfig.mockReturnValue({
|
||||
channels: {
|
||||
telegram: {
|
||||
botToken: "tok",
|
||||
},
|
||||
},
|
||||
});
|
||||
botApi.editForumTopic.mockResolvedValue(true);
|
||||
|
||||
await editForumTopicTelegram("-1001234567890", 271, {
|
||||
accountId: "default",
|
||||
name: "Codex Thread",
|
||||
iconCustomEmojiId: "emoji-123",
|
||||
});
|
||||
|
||||
expect(botApi.editForumTopic).toHaveBeenCalledWith("-1001234567890", 271, {
|
||||
name: "Codex Thread",
|
||||
icon_custom_emoji_id: "emoji-123",
|
||||
});
|
||||
});
|
||||
|
||||
it("rejects empty topic edits", async () => {
|
||||
await expect(
|
||||
editForumTopicTelegram("-1001234567890", 271, {
|
||||
accountId: "default",
|
||||
}),
|
||||
).rejects.toThrow("Telegram forum topic update requires a name or iconCustomEmojiId");
|
||||
await expect(
|
||||
editForumTopicTelegram("-1001234567890", 271, {
|
||||
accountId: "default",
|
||||
iconCustomEmojiId: " ",
|
||||
}),
|
||||
).rejects.toThrow("Telegram forum topic icon custom emoji ID is required");
|
||||
});
|
||||
|
||||
it("applies timeoutSeconds config precedence", async () => {
|
||||
const cases = [
|
||||
{
|
||||
|
||||
@@ -1128,19 +1128,39 @@ export async function unpinMessageTelegram(
|
||||
};
|
||||
}
|
||||
|
||||
export async function renameForumTopicTelegram(
|
||||
type TelegramEditForumTopicOpts = TelegramDeleteOpts & {
|
||||
name?: string;
|
||||
iconCustomEmojiId?: string;
|
||||
};
|
||||
|
||||
export async function editForumTopicTelegram(
|
||||
chatIdInput: string | number,
|
||||
messageThreadIdInput: string | number,
|
||||
name: string,
|
||||
opts: TelegramDeleteOpts = {},
|
||||
): Promise<{ ok: true; chatId: string; messageThreadId: number; name: string }> {
|
||||
const trimmedName = name.trim();
|
||||
if (!trimmedName) {
|
||||
opts: TelegramEditForumTopicOpts = {},
|
||||
): Promise<{
|
||||
ok: true;
|
||||
chatId: string;
|
||||
messageThreadId: number;
|
||||
name?: string;
|
||||
iconCustomEmojiId?: string;
|
||||
}> {
|
||||
const nameProvided = opts.name !== undefined;
|
||||
const trimmedName = opts.name?.trim();
|
||||
if (nameProvided && !trimmedName) {
|
||||
throw new Error("Telegram forum topic name is required");
|
||||
}
|
||||
if (trimmedName.length > 128) {
|
||||
if (trimmedName && trimmedName.length > 128) {
|
||||
throw new Error("Telegram forum topic name must be 128 characters or fewer");
|
||||
}
|
||||
const iconProvided = opts.iconCustomEmojiId !== undefined;
|
||||
const trimmedIconCustomEmojiId = opts.iconCustomEmojiId?.trim();
|
||||
if (iconProvided && !trimmedIconCustomEmojiId) {
|
||||
throw new Error("Telegram forum topic icon custom emoji ID is required");
|
||||
}
|
||||
if (!trimmedName && !trimmedIconCustomEmojiId) {
|
||||
throw new Error("Telegram forum topic update requires a name or iconCustomEmojiId");
|
||||
}
|
||||
|
||||
const { cfg, account, api } = resolveTelegramApiContext(opts);
|
||||
const rawTarget = String(chatIdInput);
|
||||
const chatId = await resolveAndPersistChatId({
|
||||
@@ -1157,16 +1177,39 @@ export async function renameForumTopicTelegram(
|
||||
retry: opts.retry,
|
||||
verbose: opts.verbose,
|
||||
});
|
||||
const payload = {
|
||||
...(trimmedName ? { name: trimmedName } : {}),
|
||||
...(trimmedIconCustomEmojiId ? { icon_custom_emoji_id: trimmedIconCustomEmojiId } : {}),
|
||||
};
|
||||
await requestWithDiag(
|
||||
() => api.editForumTopic(chatId, messageThreadId, { name: trimmedName }),
|
||||
() => api.editForumTopic(chatId, messageThreadId, payload),
|
||||
"editForumTopic",
|
||||
);
|
||||
logVerbose(`[telegram] Renamed forum topic ${messageThreadId} in chat ${chatId}`);
|
||||
logVerbose(`[telegram] Edited forum topic ${messageThreadId} in chat ${chatId}`);
|
||||
return {
|
||||
ok: true,
|
||||
chatId,
|
||||
messageThreadId,
|
||||
name: trimmedName,
|
||||
...(trimmedName ? { name: trimmedName } : {}),
|
||||
...(trimmedIconCustomEmojiId ? { iconCustomEmojiId: trimmedIconCustomEmojiId } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
export async function renameForumTopicTelegram(
|
||||
chatIdInput: string | number,
|
||||
messageThreadIdInput: string | number,
|
||||
name: string,
|
||||
opts: TelegramDeleteOpts = {},
|
||||
): Promise<{ ok: true; chatId: string; messageThreadId: number; name: string }> {
|
||||
const result = await editForumTopicTelegram(chatIdInput, messageThreadIdInput, {
|
||||
...opts,
|
||||
name,
|
||||
});
|
||||
return {
|
||||
ok: true,
|
||||
chatId: result.chatId,
|
||||
messageThreadId: result.messageThreadId,
|
||||
name: result.name ?? name.trim(),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user