Skip to Content
โฑ๏ธ Realtime UI (DRAFTS) ๐ŸšงTelegram Bot with Vovk.ts OpenAPI Mixins ๐Ÿšง

Bonus: Telegram bot (unstable)

As an example of a third-party source of database changes, see the TelegramServiceย  and the accompanying TelegramControllerย . It accepts text or voice messages, performs voice-to-text transcription if needed using the OpenAI Whisper API, and uses the same deriveTools function on the server.

The Telegram API library is implemented with OpenAPI Mixins and used as a TelegramAPI module to call Telegram API methods.

vovk.config.mjs
// @ts-check /** @type {import('vovk').VovkConfig} */ const config = { // ... outputConfig: { // ... segments: { telegram: { openAPIMixin: { source: { url: 'https://raw.githubusercontent.com/sys-001/telegram-bot-api-versions/refs/heads/main/files/openapi/yaml/v183.yaml', fallback: '.openapi-cache/telegram.yaml', }, getModuleName: 'TelegramAPI', getMethodName: ({ path }) => path.replace(/^\//, ''), errorMessageKey: 'description', }, }, }, }, }; export default config;

The TelegramService class handles interaction with the Telegram API and generates AI responses using the Vercel AI SDK.

src/modules/telegram/TelegramService.ts
import OpenAI from 'openai'; import { TelegramAPI } from 'vovk-client'; const openai = new OpenAI(); export default class TelegramService { static get apiRoot() { const TELEGRAM_BOT_TOKEN = process.env.TELEGRAM_BOT_TOKEN; if (!TELEGRAM_BOT_TOKEN) { throw new Error('Missing TELEGRAM_BOT_TOKEN environment variable'); } return `https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}`; } // ... private static async generateAIResponse( chatId: number, userMessage: string, systemPrompt: string ): Promise<{ botResponse: string; messages: ModelMessage[] }> { // Get chat history const history = await this.getChatHistory(chatId); const messages = [...this.formatHistoryForVercelAI(history), { role: 'user', content: userMessage } as const]; const { tools } = deriveTools({ modules: { UserController, TaskController, }, }); // Generate a response using Vercel AI SDK const { text } = await generateText({ model: vercelOpenAI('gpt-5'), system: systemPrompt, messages, stopWhen: stepCountIs(16), tools: { ...Object.fromEntries( tools.map(({ name, execute, description, parameters }) => [ name, tool({ execute, description, inputSchema: jsonSchema(parameters as JSONSchema7), }), ]) ), }, }); const botResponse = text || "I couldn't generate a response."; // Add user message to history await this.addToHistory(chatId, 'user', userMessage); // Add assistant response to history await this.addToHistory(chatId, 'assistant', botResponse); messages.push({ role: 'assistant', content: botResponse, }); return { botResponse, messages }; } private static async sendTextMessage(chatId: number, text: string): Promise<void> { await TelegramAPI.sendMessage({ body: { chat_id: chatId, text: text, parse_mode: 'html', }, apiRoot: this.apiRoot, }); } private static async sendVoiceMessage(chatId: number, text: string): Promise<void> { try { // Generate speech from text using OpenAI TTS const speechResponse = await openai.audio.speech.create({ model: 'tts-1', voice: 'alloy', input: text, response_format: 'opus', }); // Convert the response to a Buffer const voiceBuffer = Buffer.from(await speechResponse.arrayBuffer()); const formData = new FormData(); formData.append('chat_id', String(chatId)); formData.append('voice', new Blob([voiceBuffer], { type: 'audio/ogg' }), 'voice.ogg'); // Send the voice message await TelegramAPI.sendVoice({ body: formData, apiRoot: this.apiRoot, }); } catch (error) { console.error('Error generating voice message:', error); // Fallback to text message if voice generation fails await this.sendTextMessage(chatId, text); } } // ... }
Last updated on