sdelay-telegram-bota-kotoryy-3/bot.js

109 lines
4.2 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Telegraf } from "telegraf";
import { config } from "dotenv";
import fetch from "node-fetch";
import OpenAI from "openai";
config();
const bot = new Telegraf(process.env.TELEGRAM_TOKEN);
// Initialize OpenAI client environment provides base URL and API key
const openai = new OpenAI({
apiKey: process.env.AI_API_KEY,
baseURL: process.env.AI_BASE_URL,
});
// Helper: fetch recent emails via Lotus proxy
async function fetchRecentEmails(limit = 5) {
const base = process.env.LOTUS_BASE_URL;
const key = process.env.LOTUS_API_KEY;
if (!base || !key) {
return null;
}
const url = `${base}/emails?folder=inbox&count=${limit}`;
const res = await fetch(url, { headers: { Authorization: `Bearer ${key}` } });
if (!res.ok) return null;
const data = await res.json();
return data?.data || [];
}
// Helper: fetch full email by unid
async function fetchEmail(unid) {
const base = process.env.LOTUS_BASE_URL;
const key = process.env.LOTUS_API_KEY;
if (!base || !key) return null;
const url = `${base}/email/${unid}`;
const res = await fetch(url, { headers: { Authorization: `Bearer ${key}` } });
if (!res.ok) return null;
const data = await res.json();
return data?.data || null;
}
// /inbox list recent emails
bot.command("inbox", async (ctx) => {
const emails = await fetchRecentEmails();
if (!emails) {
await ctx.reply("Lotus не подключён или произошла ошибка. Проверьте интеграцию Lotus.");
return;
}
if (emails.length === 0) {
await ctx.reply("Входящих писем нет.");
return;
}
let text = "Последние письма (отправьте номер, чтобы увидеть детали):\n";
emails.forEach((mail, idx) => {
const from = mail.from?.displayName || mail.from?.email || "Неизв. отправитель";
const subj = mail.subject || "(без темы)";
text += `${idx + 1}. ${from} ${subj}\n`;
});
await ctx.reply(text);
// Store list in session for later selection
ctx.session = ctx.session || {};
ctx.session.inbox = emails;
});
// Handle numeric selection after /inbox
bot.on("text", async (ctx) => {
const txt = ctx.message.text.trim();
const num = parseInt(txt, 10);
if (ctx.session && ctx.session.inbox && !isNaN(num) && num >= 1 && num <= ctx.session.inbox.length) {
const mail = ctx.session.inbox[num - 1];
const full = await fetchEmail(mail.unid);
const body = full?.body?.text || "(нет текста)";
await ctx.reply(`*Тема:* ${mail.subject || "(без темы)"}\n*От:* ${mail.from?.displayName || mail.from?.email}\n\n${body}`, { parse_mode: "Markdown" });
// Save selected email for AI queries
ctx.session.currentMail = full;
return;
}
// If there is a selected email, treat the message as a question for AI
if (ctx.session && ctx.session.currentMail) {
const question = txt;
const emailText = ctx.session.currentMail.body?.text || "";
try {
const completion = await openai.chat.completions.create({
model: process.env.AI_MODEL || "gpt-4o-mini",
messages: [
{ role: "system", content: "Ты помогаешь отвечать на вопросы пользователя, используя содержание письма из Lotus. Сформулируй ответ кратко и по существу." },
{ role: "user", content: `Письмо:
${emailText}\n\nВопрос пользователя: ${question}` },
],
max_tokens: 500,
});
const answer = completion.choices[0].message.content;
await ctx.reply(answer);
} catch (e) {
await ctx.reply("Ошибка при обращении к AI: " + e.message);
}
return;
}
// Default fallback
await ctx.reply("Используй /inbox чтобы посмотреть последние письма, затем отправь номер письма. После этого можешь задавать вопросы, и я отвечу, используя содержание письма.");
});
bot.launch();
process.once("SIGINT", () => bot.stop("SIGINT"));
process.once("SIGTERM", () => bot.stop("SIGTERM"));