add: topic channel id support

This commit is contained in:
Théo LAGACHE
2026-03-02 10:27:21 +01:00
parent f1edffed17
commit f04503e38e
2 changed files with 67 additions and 38 deletions
@@ -43,6 +43,22 @@ export const NotifierTelegramForm = ({form}: NotifierTelegramFormProps) => {
</FormItem> </FormItem>
)} )}
/> />
<FormField
control={form.control}
name="config.telegramTopicId"
render={({field}) => (
<FormItem>
<FormLabel>Telegram Topic ID</FormLabel>
<FormControl>
<Input {...field} placeholder="123456"/>
</FormControl>
<p className="text-xs text-muted-foreground">
Unique identifier for the target message thread (topic) of the forum; for forum supergroups only
</p>
<FormMessage/>
</FormItem>
)}
/>
</> </>
) )
} }
@@ -1,49 +1,62 @@
import type {EventPayload, DispatchResult} from '../types'; import type { EventPayload, DispatchResult } from "../types";
export async function sendTelegram( export async function sendTelegram(
config: { telegramBotToken: string; telegramChatId: string }, config: {
payload: EventPayload telegramBotToken: string;
telegramChatId: string;
telegramTopicId?: string;
},
payload: EventPayload,
): Promise<DispatchResult> { ): Promise<DispatchResult> {
const {telegramBotToken, telegramChatId} = config; const { telegramBotToken, telegramChatId, telegramTopicId } = config;
// Helper to escape HTML characters // Helper to escape HTML characters
const escapeHtml = (unsafe: string) => { const escapeHtml = (unsafe: string) => {
return unsafe return unsafe
.replace(/&/g, "&amp;") .replace(/&/g, "&amp;")
.replace(/</g, "&lt;") .replace(/</g, "&lt;")
.replace(/>/g, "&gt;") .replace(/>/g, "&gt;")
.replace(/"/g, "&quot;") .replace(/"/g, "&quot;")
.replace(/'/g, "&#039;"); .replace(/'/g, "&#039;");
}; };
const title = escapeHtml(payload.title); const title = escapeHtml(payload.title);
const message = escapeHtml(payload.message); const message = escapeHtml(payload.message);
const level = escapeHtml(payload.level.toUpperCase()); const level = escapeHtml(payload.level.toUpperCase());
const dataString = payload.data ? escapeHtml(JSON.stringify(payload.data, null, 2).substring(0, 1000)) : ''; const dataString = payload.data
? escapeHtml(JSON.stringify(payload.data, null, 2).substring(0, 1000))
: "";
const text = `<b>${title}</b>\n\n${message}\n\nLevel: <code>${level}</code>${payload.data ? `\n\nData:\n<pre>${dataString}</pre>` : ''}`; const text = `<b>${title}</b>\n\n${message}\n\nLevel: <code>${level}</code>${payload.data ? `\n\nData:\n<pre>${dataString}</pre>` : ""}`;
const body = { const body: Record<string, any> = {
chat_id: telegramChatId, chat_id: telegramChatId,
text, text,
parse_mode: 'HTML', parse_mode: "HTML",
}; };
const res = await fetch(`https://api.telegram.org/bot${telegramBotToken}/sendMessage`, { if (telegramTopicId) {
method: 'POST', body.message_thread_id = Number(telegramTopicId);
body: JSON.stringify(body), }
headers: {'Content-Type': 'application/json'},
});
if (!res.ok) { const res = await fetch(
const err = await res.text(); `https://api.telegram.org/bot${telegramBotToken}/sendMessage`,
throw new Error(`Telegram error: ${res.status} ${err}`); {
} method: "POST",
body: JSON.stringify(body),
headers: { "Content-Type": "application/json" },
},
);
return { if (!res.ok) {
success: true, const err = await res.text();
provider: 'telegram', throw new Error(`Telegram error: ${res.status} ${err}`);
message: 'Sent to Telegram', }
response: await res.text(),
}; return {
success: true,
provider: "telegram",
message: "Sent to Telegram",
response: await res.text(),
};
} }