Initial commit: Complete Quixotic Telegram MiniApp implementation
- Set up Express.js server with YouTube search and MP3 conversion API - Created Telegram Web App frontend with responsive design - Implemented SQLite database for user management and history - Added Telegram Bot integration with commands and Web App support - Configured FFmpeg-based audio conversion pipeline - Added comprehensive documentation and deployment guides 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
104
src/database.js
Normal file
104
src/database.js
Normal file
@@ -0,0 +1,104 @@
|
||||
const sqlite3 = require('sqlite3').verbose();
|
||||
const path = require('path');
|
||||
|
||||
class Database {
|
||||
constructor() {
|
||||
this.dbPath = path.join(__dirname, '../database/quixotic.db');
|
||||
this.db = new sqlite3.Database(this.dbPath);
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
this.db.serialize(() => {
|
||||
// Users table
|
||||
this.db.run(`CREATE TABLE IF NOT EXISTS users (
|
||||
id INTEGER PRIMARY KEY,
|
||||
telegram_id INTEGER UNIQUE NOT NULL,
|
||||
username TEXT,
|
||||
first_name TEXT,
|
||||
last_name TEXT,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
)`);
|
||||
|
||||
// Search history table
|
||||
this.db.run(`CREATE TABLE IF NOT EXISTS search_history (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER,
|
||||
query TEXT NOT NULL,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (user_id) REFERENCES users (id)
|
||||
)`);
|
||||
|
||||
// Downloaded files table
|
||||
this.db.run(`CREATE TABLE IF NOT EXISTS downloads (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER,
|
||||
youtube_id TEXT NOT NULL,
|
||||
title TEXT NOT NULL,
|
||||
file_path TEXT,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (user_id) REFERENCES users (id)
|
||||
)`);
|
||||
});
|
||||
}
|
||||
|
||||
addUser(telegramUser) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const { id, username, first_name, last_name } = telegramUser;
|
||||
this.db.run(
|
||||
`INSERT OR REPLACE INTO users (telegram_id, username, first_name, last_name)
|
||||
VALUES (?, ?, ?, ?)`,
|
||||
[id, username, first_name, last_name],
|
||||
function(err) {
|
||||
if (err) reject(err);
|
||||
else resolve(this.lastID);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
addSearchHistory(userId, query) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.db.run(
|
||||
`INSERT INTO search_history (user_id, query) VALUES (?, ?)`,
|
||||
[userId, query],
|
||||
function(err) {
|
||||
if (err) reject(err);
|
||||
else resolve(this.lastID);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
addDownload(userId, youtubeId, title, filePath) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.db.run(
|
||||
`INSERT INTO downloads (user_id, youtube_id, title, file_path) VALUES (?, ?, ?, ?)`,
|
||||
[userId, youtubeId, title, filePath],
|
||||
function(err) {
|
||||
if (err) reject(err);
|
||||
else resolve(this.lastID);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
getUserByTelegramId(telegramId) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.db.get(
|
||||
`SELECT * FROM users WHERE telegram_id = ?`,
|
||||
[telegramId],
|
||||
(err, row) => {
|
||||
if (err) reject(err);
|
||||
else resolve(row);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
close() {
|
||||
this.db.close();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Database;
|
||||
Reference in New Issue
Block a user