armyan tts add
This commit is contained in:
155
bot.js
155
bot.js
@@ -4,6 +4,18 @@ import axios from "axios";
|
|||||||
import FormData from 'form-data';
|
import FormData from 'form-data';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
|
|
||||||
|
import ffmpeg from 'fluent-ffmpeg';
|
||||||
|
|
||||||
|
function convertToOgg(inputPath, outputPath) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
ffmpeg(inputPath)
|
||||||
|
.audioCodec('libopus')
|
||||||
|
.format('ogg')
|
||||||
|
.on('end', () => resolve())
|
||||||
|
.on('error', (err) => reject(err))
|
||||||
|
.save(outputPath);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
import { UserRepository } from "./user.repository.js";
|
import { UserRepository } from "./user.repository.js";
|
||||||
|
|
||||||
@@ -18,39 +30,42 @@ const bot = new TelegramBot(tokenTg, { polling: true });
|
|||||||
console.log("Бот запущен...");
|
console.log("Бот запущен...");
|
||||||
|
|
||||||
|
|
||||||
bot.onText(/\/info/, (msg)=>{
|
bot.onText(/\/info/, (msg) => {
|
||||||
const message = `Информация о боте: \n
|
const message = `Информация о боте: \n
|
||||||
'/start' - перезапускает чат, забывает контекст прошлого диалого \n
|
'/start' - перезапускает чат, забывает контекст прошлого диалого \n
|
||||||
'/toggleModel' - Выбор модели (еще не доступен)`
|
'/toggleModel' - Выбор модели (еще не доступен)`
|
||||||
const chatId = msg.chat.id
|
const chatId = msg.chat.id
|
||||||
|
|
||||||
bot.sendMessage(chatId, message)
|
bot.sendMessage(chatId, message)
|
||||||
})
|
})
|
||||||
|
|
||||||
bot.onText(/\/armyan (.+)/, async(msg, match)=>{
|
bot.onText(/\/armyan (.+)/, async (msg, match) => {
|
||||||
const chatId = msg.chat.id;
|
const chatId = msg.chat.id;
|
||||||
const textAfterCommand = match[1];
|
const textAfterCommand = match[1];
|
||||||
|
const response = await textToArmyan(textAfterCommand);
|
||||||
|
await convertToOgg(`voices/${response.file}.wav`, `voices/${response.file}.ogg`);
|
||||||
|
bot.sendVoice(chatId, `voices/${response.file}.ogg`);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
bot.onText(/\/start/, async(msg) => {
|
bot.onText(/\/start/, async (msg) => {
|
||||||
const chatId = msg.chat.id;
|
const chatId = msg.chat.id;
|
||||||
const chatType = msg.chat.type
|
const chatType = msg.chat.type
|
||||||
const user = msg.from
|
const user = msg.from
|
||||||
try{
|
try {
|
||||||
const createOrUpdateUser = await UserRepository.createOrUpdateUser({
|
const createOrUpdateUser = await UserRepository.createOrUpdateUser({
|
||||||
telegramId: user.id,
|
telegramId: user.id,
|
||||||
username: user.username,
|
username: user.username,
|
||||||
chatId: chatId
|
chatId: chatId
|
||||||
});
|
});
|
||||||
}catch(err){
|
} catch (err) {
|
||||||
console.error('Ошибка при создании или обновлении пользователя:', err);
|
console.error('Ошибка при создании или обновлении пользователя:', err);
|
||||||
}
|
}
|
||||||
bot.sendMessage(chatId, `Чат перезапущен, тип чата ${chatType}`);
|
bot.sendMessage(chatId, `Чат перезапущен, тип чата ${chatType}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
bot.on('message', async(msg) => {
|
bot.on('message', async (msg) => {
|
||||||
const chatId = msg.chat.id;
|
const chatId = msg.chat.id;
|
||||||
|
|
||||||
const user = msg.from
|
const user = msg.from
|
||||||
@@ -62,115 +77,155 @@ bot.on('message', async(msg) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (msg.photo) {
|
if (msg.photo) {
|
||||||
bot.sendMessage(chatId, 'Красиво, но такое мне не надо', {reply_to_message_id: msg.message_id});
|
bot.sendMessage(chatId, 'Красиво, но такое мне не надо', { reply_to_message_id: msg.message_id });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg.document) {
|
if (msg.document) {
|
||||||
bot.sendMessage(chatId, 'Такое мне не надо', {reply_to_message_id: msg.message_id});
|
bot.sendMessage(chatId, 'Такое мне не надо', { reply_to_message_id: msg.message_id });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg.from.is_bot){
|
if (msg.from.is_bot) {
|
||||||
bot.sendMessage(chatId, 'Пошел нахуй бот ебанный, не мешай слушать брата', {reply_to_message_id: msg.message_id});
|
bot.sendMessage(chatId, 'Пошел нахуй бот ебанный, не мешай слушать брата', { reply_to_message_id: msg.message_id });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg.voice ){
|
if (msg.voice) {
|
||||||
const fileId = msg.voice.file_id;
|
const fileId = msg.voice.file_id;
|
||||||
|
|
||||||
const filePath = await bot.downloadFile(fileId, './voices');
|
const filePath = await bot.downloadFile(fileId, './voices');
|
||||||
|
|
||||||
const form = new FormData();
|
const form = new FormData();
|
||||||
form.append('file', fs.createReadStream(filePath));
|
form.append('file', fs.createReadStream(filePath));
|
||||||
|
|
||||||
const response = await axios.post(
|
const response = await axios.post(
|
||||||
'http://10.8.1.2:3000/upload',
|
`http://${process.env.API_URL}:${process.env.API_PORT}/upload`,
|
||||||
form,
|
form,
|
||||||
{
|
{
|
||||||
headers: form.getHeaders()
|
headers: form.getHeaders()
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if(response.status === 200){
|
if (response.status === 200) {
|
||||||
const recognizedText = response.data.text;
|
const recognizedText = response.data.text;
|
||||||
bot.sendMessage(chatId, recognizedText, {reply_to_message_id: msg.message_id});
|
bot.sendMessage(chatId, recognizedText, { reply_to_message_id: msg.message_id });
|
||||||
}else{
|
} else {
|
||||||
bot.sendMessage(chatId, 'Что-то пошло не так', {reply_to_message_id: msg.message_id});
|
bot.sendMessage(chatId, 'Что-то пошло не так', { reply_to_message_id: msg.message_id });
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg.text && user.id === 5536333712){
|
if (msg.text && user.id === 5536333712) {
|
||||||
console.log('Армянин, переключаем модель')
|
console.log('Армянин, переключаем модель')
|
||||||
const response = await switchToRussian(msg.text);
|
const response = await switchToRussian(msg.text);
|
||||||
bot.sendMessage(chatId, response.message, {reply_to_message_id: msg.message_id});
|
bot.sendMessage(chatId, response.message, { reply_to_message_id: msg.message_id });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg.text && msg.chat.type === 'private') {
|
if (msg.text && msg.chat.type === 'private') {
|
||||||
//bot.sendMessage(chatId, `Ты написал: ${msg.text}`);
|
//bot.sendMessage(chatId, `Ты написал: ${msg.text}`);
|
||||||
try{
|
try {
|
||||||
const last_msg_context = await UserRepository.getContext(user.id) || ''
|
const last_msg_context = await UserRepository.getContext(user.id) || ''
|
||||||
console.log('last_msg_context:', last_msg_context);
|
console.log('last_msg_context:', last_msg_context);
|
||||||
if(last_msg_context === ''){
|
if (last_msg_context === '') {
|
||||||
console.log('Новый пользователь, начинаем диалог с чистого листа');
|
console.log('Новый пользователь, начинаем диалог с чистого листа');
|
||||||
const response = await getAIResponse(msg.text, null);
|
const response = await getAIResponse(msg.text, null);
|
||||||
bot.sendMessage(chatId, response.message);
|
bot.sendMessage(chatId, response.message);
|
||||||
await UserRepository.updateContext(user.id, response.id);
|
await UserRepository.updateContext(user.id, response.id);
|
||||||
}else{
|
} else {
|
||||||
console.log('Продолжаем диалог, контекст найден');
|
console.log('Продолжаем диалог, контекст найден');
|
||||||
const response = await getAIResponse(msg.text, last_msg_context);
|
const response = await getAIResponse(msg.text, last_msg_context);
|
||||||
bot.sendMessage(chatId, response.message);
|
bot.sendMessage(chatId, response.message);
|
||||||
await UserRepository.updateContext(user.id, response.id);
|
await UserRepository.updateContext(user.id, response.id);
|
||||||
}
|
}
|
||||||
}catch(err){
|
} catch (err) {
|
||||||
console.error('Ошибка при обработке сообщения:', err);
|
console.error('Ошибка при обработке сообщения:', err);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
async function switchToRussian(message){
|
async function switchToRussian(message) {
|
||||||
try{
|
try {
|
||||||
const options = {
|
const options = {
|
||||||
method:'POST',
|
method: 'POST',
|
||||||
url:`https://agent.timeweb.cloud/api/v1/cloud-ai/agents/${accessId}/call`,
|
url: `https://agent.timeweb.cloud/api/v1/cloud-ai/agents/${accessId}/call`,
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${tokenAi}`,
|
Authorization: `Bearer ${tokenAi}`,
|
||||||
'x-proxy-source': '',
|
'x-proxy-source': '',
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
},
|
},
|
||||||
data:{
|
data: {
|
||||||
message: `Убери ошибки в тексте и поставь знаки препинания: "${message}". Если текст короткий или без явных ошибок ничего не делай и отвечай просто "Армянин молодец", особо не размышляй над содержимым текста, просто выполняй свою задачу. Так же делай рядом версию с переводом на армянский язык`,
|
message: `Убери ошибки в тексте и поставь знаки препинания: "${message}". Если текст короткий или без явных ошибок ничего не делай и отвечай просто "Армянин молодец", особо не размышляй над содержимым текста, просто выполняй свою задачу. Так же делай рядом версию с переводом на армянский язык`,
|
||||||
parent_message_id: ''
|
parent_message_id: ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const response = await axios.request(options);
|
const response = await axios.request(options);
|
||||||
return response.data;
|
return response.data;
|
||||||
}catch(err){
|
} catch (err) {
|
||||||
console.error('Ошибка при получении ответа от AI:', err);
|
console.error('Ошибка при получении ответа от AI:', err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getAIResponse(message, context) {
|
async function getAIResponse(message, context) {
|
||||||
try{
|
try {
|
||||||
const options = {
|
const options = {
|
||||||
method:'POST',
|
method: 'POST',
|
||||||
url:`https://agent.timeweb.cloud/api/v1/cloud-ai/agents/${accessId}/call`,
|
url: `https://agent.timeweb.cloud/api/v1/cloud-ai/agents/${accessId}/call`,
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${tokenAi}`,
|
Authorization: `Bearer ${tokenAi}`,
|
||||||
'x-proxy-source': '',
|
'x-proxy-source': '',
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
},
|
},
|
||||||
data:{
|
data: {
|
||||||
message: message,
|
message: message,
|
||||||
parent_message_id: context
|
parent_message_id: context
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const response = await axios.request(options);
|
const response = await axios.request(options);
|
||||||
return response.data;
|
return response.data;
|
||||||
}catch(err){
|
} catch (err) {
|
||||||
|
console.error('Ошибка при получении ответа от AI:', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function textToArmyan(message) {
|
||||||
|
try {
|
||||||
|
const optionsArmyan = {
|
||||||
|
method: 'POST',
|
||||||
|
url: `https://agent.timeweb.cloud/api/v1/cloud-ai/agents/${accessId}/call`,
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${tokenAi}`,
|
||||||
|
'x-proxy-source': '',
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
message: `Переведи текст на армянский, ничего не добаляй от себя, просто переведи: '${message}'`,
|
||||||
|
parent_message_id: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const responseArmyan = await axios.request(optionsArmyan);
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
method: 'POST',
|
||||||
|
url: `http://${process.env.API_URL}:${process.env.API_PORT}/voice/start`,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
text: responseArmyan.data.message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const response = await axios.request(options);
|
||||||
|
if (response.status === 200) {
|
||||||
|
return response.data;
|
||||||
|
} else {
|
||||||
|
console.error('Ошибка при получении ответа от AI:', response.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
console.error('Ошибка при получении ответа от AI:', err);
|
console.error('Ошибка при получении ответа от AI:', err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,4 +6,8 @@ DATABASE_NAME =
|
|||||||
DATABASE_URL =
|
DATABASE_URL =
|
||||||
DATABASE_USER =
|
DATABASE_USER =
|
||||||
DATABASE_PASSWORD =
|
DATABASE_PASSWORD =
|
||||||
GEMINI_KEY =
|
GEMINI_KEY =
|
||||||
|
PORT = 3000
|
||||||
|
JWT_SECRET = super_secret_key_123
|
||||||
|
API_URL = 10.8.1.3
|
||||||
|
API_PORT = 3000
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
"cors": "^2.8.6",
|
"cors": "^2.8.6",
|
||||||
"dotenv": "^17.2.3",
|
"dotenv": "^17.2.3",
|
||||||
"express": "^5.2.1",
|
"express": "^5.2.1",
|
||||||
|
"fluent-ffmpeg": "^2.1.3",
|
||||||
"form-data": "^4.0.5",
|
"form-data": "^4.0.5",
|
||||||
"jsonwebtoken": "^9.0.3",
|
"jsonwebtoken": "^9.0.3",
|
||||||
"multer": "^2.0.2",
|
"multer": "^2.0.2",
|
||||||
|
|||||||
@@ -8,30 +8,29 @@ import { GoogleGenAI, createUserContent, createPartFromUri } from "@google/genai
|
|||||||
import dotenv from "dotenv";
|
import dotenv from "dotenv";
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
||||||
import wav from 'wav';
|
|
||||||
import { text } from "stream/consumers";
|
import { text } from "stream/consumers";
|
||||||
|
|
||||||
async function shneine(fileName, mimeType){
|
async function shneine(fileName, mimeType) {
|
||||||
const myfile = await ai.files.upload({
|
const myfile = await ai.files.upload({
|
||||||
file:`./uploads/${fileName}`,
|
file: `./uploads/${fileName}`,
|
||||||
config:{
|
config: {
|
||||||
mimeType:mimeType,
|
mimeType: mimeType,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const response = await ai.models.generateContent({
|
const response = await ai.models.generateContent({
|
||||||
model: "gemini-3-flash-preview",
|
model: "gemini-3-flash-preview",
|
||||||
contents: createUserContent([
|
contents: createUserContent([
|
||||||
createPartFromUri(myfile.uri, myfile.mimeType),
|
createPartFromUri(myfile.uri, myfile.mimeType),
|
||||||
'Что дословно говорится в этом аудиофайле? отвечай сухо, чисто текст, может исправить ошибки в тексте и поставить знаки препинания. Если звуковая дорожка маленькая 1-2 секунды и в ней нету слов или не понятна, отвечай "Армянин молодец, напердел". Так же делай рядом версию с переводом на армянский язык'
|
'Что дословно говорится в этом аудиофайле? отвечай сухо, чисто текст, может исправить ошибки в тексте и поставить знаки препинания. Если звуковая дорожка маленькая 1-2 секунды и в ней нету слов или не понятна, отвечай "Армянин молодец, напердел". Так же делай рядом версию с переводом на армянский язык'
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
return response.text;
|
return response.text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// The client gets the API key from the environment variable `GEMINI_API_KEY`.
|
// The client gets the API key from the environment variable `GEMINI_API_KEY`.
|
||||||
const ai = new GoogleGenAI({apiKey: process.env.GEMINI_KEY});
|
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_KEY });
|
||||||
|
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
@@ -58,7 +57,7 @@ const storage = multer.diskStorage({
|
|||||||
const upload = multer({
|
const upload = multer({
|
||||||
storage,
|
storage,
|
||||||
limits: {
|
limits: {
|
||||||
fileSize: 50 * 1024 * 1024, // 5 MB
|
fileSize: 500 * 1024 * 1024, // 5 MB
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,15 @@ import { Router } from "express";
|
|||||||
import multer from "multer";
|
import multer from "multer";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
|
import wav from "wav";
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
import { GoogleGenAI, createUserContent, createPartFromUri } from "@google/genai";
|
import { GoogleGenAI, createUserContent, createPartFromUri } from "@google/genai";
|
||||||
import dotenv from "dotenv";
|
import dotenv from "dotenv";
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
||||||
|
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_KEY });
|
||||||
|
|
||||||
async function saveWaveFile(
|
async function saveWaveFile(
|
||||||
filename,
|
filename,
|
||||||
pcmData,
|
pcmData,
|
||||||
@@ -17,9 +20,9 @@ async function saveWaveFile(
|
|||||||
) {
|
) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const writer = new wav.FileWriter(filename, {
|
const writer = new wav.FileWriter(filename, {
|
||||||
channels,
|
channels,
|
||||||
sampleRate: rate,
|
sampleRate: rate,
|
||||||
bitDepth: sampleWidth * 8,
|
bitDepth: sampleWidth * 8,
|
||||||
});
|
});
|
||||||
|
|
||||||
writer.on('finish', resolve);
|
writer.on('finish', resolve);
|
||||||
@@ -30,34 +33,63 @@ async function saveWaveFile(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fawatafa() {
|
const voicesDir = "voices";
|
||||||
|
if (!fs.existsSync(voicesDir)) {
|
||||||
|
fs.mkdirSync(voicesDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
const storage = multer.diskStorage({
|
||||||
|
destination: (req, file, cb) => {
|
||||||
|
cb(null, voicesDir);
|
||||||
|
},
|
||||||
|
filename: (req, file, cb) => {
|
||||||
|
const uniqueName =
|
||||||
|
Date.now() + "-" + Math.round(Math.random() * 1e9);
|
||||||
|
|
||||||
|
const ext = path.extname(file.originalname);
|
||||||
|
cb(null, uniqueName + ext);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const upload = multer({
|
||||||
|
storage,
|
||||||
|
limits: {
|
||||||
|
fileSize: 500 * 1024 * 1024, // 50 MB
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
async function fawatafa(text) {
|
||||||
const response = await ai.models.generateContent({
|
const response = await ai.models.generateContent({
|
||||||
model: "gemini-2.5-flash-preview-tts",
|
model: "gemini-2.5-flash-preview-tts",
|
||||||
contents: [{ parts: [{ text: `Say aggresive: А перекинул я этот пост, потому что его Саша переслал. И вот вдумайся: Саше 30 лет, и вот на него это полностью работает. То есть он верит, что можно заставить Дурова открыть представительство в России, и это снимет к нему все вопросы, и Телеграм оставят незаблокированным` }] }],
|
contents: [{ parts: [{ text: `Say aggresive: ${text}` }] }],
|
||||||
config: {
|
config: {
|
||||||
responseModalities: ['AUDIO'],
|
responseModalities: ['AUDIO'],
|
||||||
speechConfig: {
|
speechConfig: {
|
||||||
voiceConfig: {
|
voiceConfig: {
|
||||||
prebuiltVoiceConfig: { voiceName: 'Leda' },
|
prebuiltVoiceConfig: { voiceName: 'Sadaltager' },
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const data = response.candidates?.[0]?.content?.parts?.[0]?.inlineData?.data;
|
const data = response.candidates?.[0]?.content?.parts?.[0]?.inlineData?.data;
|
||||||
const audioBuffer = Buffer.from(data, 'base64');
|
const audioBuffer = Buffer.from(data, 'base64');
|
||||||
|
const file = Date.now() + "-" + Math.round(Math.random() * 1e9);
|
||||||
const fileName = 'outMarat5.wav';
|
const fileName = `${file}.wav`;
|
||||||
await saveWaveFile(fileName, audioBuffer);
|
const filePath = path.join(voicesDir, fileName);
|
||||||
|
await saveWaveFile(filePath, audioBuffer);
|
||||||
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
router.post('/voice', async(req, res) => {
|
router.post('/start', async (req, res) => {
|
||||||
try{
|
try {
|
||||||
|
const text = req.body.text;
|
||||||
}catch(err){
|
const fileName = await fawatafa(text);
|
||||||
console.error('Ошибка при обработке голосового сообщения:', err);
|
res.status(200).json({ message: 'Голосовое сообщение успешно обработано', file: fileName });
|
||||||
res.status(500).json({ message: 'Ошибка при обработке голосового сообщения' });
|
} catch (err) {
|
||||||
}
|
console.error('Ошибка при обработке голосового сообщения:', err);
|
||||||
|
res.status(500).json({ message: 'Ошибка при обработке голосового сообщения' });
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import cors from 'cors'
|
|||||||
import authRoutes from "./routes/auth.js";
|
import authRoutes from "./routes/auth.js";
|
||||||
import userRoutes from "./routes/user.js";
|
import userRoutes from "./routes/user.js";
|
||||||
import uploadRoutes from "./routes/upload.js";
|
import uploadRoutes from "./routes/upload.js";
|
||||||
|
import voiceRoutes from "./routes/voice.js";
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
@@ -17,6 +17,7 @@ app.use(cors());
|
|||||||
app.use("/auth", authRoutes);
|
app.use("/auth", authRoutes);
|
||||||
app.use("/user", userRoutes);
|
app.use("/user", userRoutes);
|
||||||
app.use("/upload", uploadRoutes);
|
app.use("/upload", uploadRoutes);
|
||||||
|
app.use("/voice", voiceRoutes);
|
||||||
|
|
||||||
|
|
||||||
app.get("/health", (req, res) => {
|
app.get("/health", (req, res) => {
|
||||||
@@ -25,6 +26,6 @@ app.get("/health", (req, res) => {
|
|||||||
|
|
||||||
const PORT = process.env.PORT || 3000;
|
const PORT = process.env.PORT || 3000;
|
||||||
const HOST = "0.0.0.0"
|
const HOST = "0.0.0.0"
|
||||||
app.listen(PORT,"0.0.0.0", () => {
|
app.listen(PORT, "0.0.0.0", () => {
|
||||||
console.log(`🚀 Server started on http://localhost:${PORT}`);
|
console.log(`🚀 Server started on http://localhost:${PORT}`);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user