kaneo (minimalist kanban) fork to experiment adding a tangled integration github.com/usekaneo/kaneo
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at cd7cada2f86b4e866a15b4323bb8d6d7ab5bba8b 91 lines 2.3 kB view raw
1import * as v from "valibot"; 2 3export const telegramEventKeys = [ 4 "taskCreated", 5 "taskStatusChanged", 6 "taskPriorityChanged", 7 "taskTitleChanged", 8 "taskDescriptionChanged", 9 "taskCommentCreated", 10] as const; 11 12export type TelegramEventKey = (typeof telegramEventKeys)[number]; 13 14export const telegramEventsSchema = v.object( 15 Object.fromEntries( 16 telegramEventKeys.map((key) => [key, v.optional(v.boolean())]), 17 ) as Record< 18 TelegramEventKey, 19 v.OptionalSchema<v.BooleanSchema<undefined>, never> 20 >, 21); 22 23const telegramBotTokenSchema = v.pipe( 24 v.string(), 25 v.regex(/^\d{8,10}:[A-Za-z0-9_-]{35}$/, "Enter a valid Telegram bot token"), 26); 27 28const telegramChatIdSchema = v.pipe( 29 v.string(), 30 v.trim(), 31 v.minLength(1, "Chat ID is required"), 32); 33 34export const telegramConfigSchema = v.object({ 35 botToken: telegramBotTokenSchema, 36 chatId: telegramChatIdSchema, 37 threadId: v.optional(v.pipe(v.number(), v.integer(), v.minValue(1))), 38 chatLabel: v.optional(v.string()), 39 events: v.optional(telegramEventsSchema), 40}); 41 42export type TelegramConfig = v.InferOutput<typeof telegramConfigSchema>; 43 44export const defaultTelegramEvents: Record<TelegramEventKey, boolean> = { 45 taskCreated: true, 46 taskStatusChanged: true, 47 taskPriorityChanged: false, 48 taskTitleChanged: false, 49 taskDescriptionChanged: false, 50 taskCommentCreated: true, 51}; 52 53export function normalizeTelegramConfig( 54 config: TelegramConfig, 55): TelegramConfig { 56 return { 57 ...config, 58 threadId: 59 typeof config.threadId === "number" && Number.isFinite(config.threadId) 60 ? config.threadId 61 : undefined, 62 chatLabel: config.chatLabel?.trim() || undefined, 63 events: { 64 ...defaultTelegramEvents, 65 ...(config.events ?? {}), 66 }, 67 }; 68} 69 70export function validateTelegramConfig(config: unknown): { 71 valid: boolean; 72 errors?: string[]; 73} { 74 try { 75 const parsed = v.parse(telegramConfigSchema, config); 76 normalizeTelegramConfig(parsed); 77 return { valid: true }; 78 } catch (error) { 79 if (error instanceof v.ValiError) { 80 return { 81 valid: false, 82 errors: error.issues.map((issue) => issue.message), 83 }; 84 } 85 86 return { 87 valid: false, 88 errors: [error instanceof Error ? error.message : "Invalid config"], 89 }; 90 } 91}