feat: MedSchedule модуль — семейный медицинский помощник с Telegram/MAX ботом, n8n OCR и /med UI

This commit is contained in:
2026-07-15 09:42:55 +03:00
parent d35d0cd1ef
commit f519ce95db
15 changed files with 2960 additions and 2 deletions

View File

@@ -0,0 +1,90 @@
export type BotPlatform = "telegram" | "max";
const TELEGRAM_API_BASE = "https://api.telegram.org/bot";
const MAX_API_BASE = process.env.MAX_BOT_API_BASE || "https://api.max.ru/bot";
export async function sendBotMessage(
platform: BotPlatform,
chatId: string,
text: string,
options?: {
parseMode?: "HTML" | "Markdown";
replyMarkup?: any;
token?: string;
}
): Promise<{ ok: boolean; error?: string }> {
const token = options?.token || (platform === "telegram" ? process.env.TELEGRAM_BOT_TOKEN : process.env.MAX_BOT_TOKEN);
if (!token) {
return { ok: false, error: `Token not configured for ${platform}` };
}
const base = platform === "telegram" ? `${TELEGRAM_API_BASE}${token}` : `${MAX_API_BASE}${token}`;
const url = `${base}/sendMessage`;
try {
const body: Record<string, any> = {
chat_id: chatId,
text,
};
if (options?.parseMode) body.parse_mode = options.parseMode;
if (options?.replyMarkup) body.reply_markup = options.replyMarkup;
const response = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
});
if (!response.ok) {
const errText = await response.text();
console.error(`[${platform}] sendMessage error ${response.status}:`, errText);
return { ok: false, error: errText };
}
return { ok: true };
} catch (err: any) {
console.error(`[${platform}] sendMessage failed:`, err);
return { ok: false, error: err.message || "Request failed" };
}
}
export async function sendBotPhoto(
platform: BotPlatform,
chatId: string,
photoUrl: string,
caption?: string,
options?: { token?: string }
): Promise<{ ok: boolean; error?: string }> {
const token = options?.token || (platform === "telegram" ? process.env.TELEGRAM_BOT_TOKEN : process.env.MAX_BOT_TOKEN);
if (!token) {
return { ok: false, error: `Token not configured for ${platform}` };
}
const base = platform === "telegram" ? `${TELEGRAM_API_BASE}${token}` : `${MAX_API_BASE}${token}`;
const url = `${base}/sendPhoto`;
try {
const body: Record<string, any> = {
chat_id: chatId,
photo: photoUrl,
};
if (caption) body.caption = caption;
const response = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
});
if (!response.ok) {
const errText = await response.text();
console.error(`[${platform}] sendPhoto error ${response.status}:`, errText);
return { ok: false, error: errText };
}
return { ok: true };
} catch (err: any) {
console.error(`[${platform}] sendPhoto failed:`, err);
return { ok: false, error: err.message || "Request failed" };
}
}