MVP-Feedback-Bot für Max.ru mit Long Polling und SQLite erstellen
Max.ru bietet Entwicklern Zugriff auf seine Bot-API zur Erstellung interaktiver Tools. Für diesen MVP-Feedback-Bot verwenden wir Node.js mit der Bibliothek @maxhub/max-bot-api und SQLite. Long Polling ermöglicht die lokale Entwicklung ohne Webhooks, Server oder HTTPS.
Die zentrale Herausforderung besteht darin, den Client zu identifizieren, wenn der Admin antwortet. Antwortnachrichten enthalten einen Link mit der mid der ursprünglichen Nachricht, sodass wir Antworten über die Datenbank zurückverfolgen können.
Technologie-Stack auswählen und Projekt einrichten
Die Bibliothek @maxhub/max-bot-api unterstützt Long Polling standardmäßig – keine Notwendigkeit für ngrok oder Cloudflare Tunnel während der Entwicklung.
SQLite ist ideal für MVPs: es handelt sich um eine dateibasierte Datenbank ohne separaten Server, mit minimaler Latenz und konsistenter Anfragenverarbeitung.
Abhängigkeiten installieren:
npm init -y
npm install @maxhub/max-bot-api sqlite sqlite3 dotenv
Eine .env-Datei erstellen:
BOT_TOKEN=dein_token_hier
OWNER_ID=12345678
Der Token wird in business.max.ru generiert, und OWNER_ID ist Ihre persönliche Max-User-ID.
SQLite initialisieren und Datenbankschema erstellen
Asynchrone Verbindung herstellen und die reply_map-Tabelle für die Zuordnung erstellen:
import { open } from 'sqlite';
import sqlite3 from 'sqlite3';
let db;
(async () => {
db = await open({ filename: './database.sqlite', driver: sqlite3.Database });
await db.exec(`
CREATE TABLE IF NOT EXISTS reply_map (
owner_msg_mid TEXT PRIMARY KEY,
client_user_id INTEGER
)
`);
console.log('Datenbank bereit');
})();
Diese Tabelle speichert die Zuordnung von owner_msg_mid zu client_user_id.
Nachrichten von Clients verarbeiten
Das message_created-Ereignis prüft den Absender. Client-Nachrichten werden an den Admin mit Markdown-Formatierung weitergeleitet:
const ownerId = Number(process.env.OWNER_ID);
bot.on('message_created', async (ctx) => {
const msg = ctx.message;
const senderId = msg.sender.user_id;
const text = msg.body.text;
if (senderId !== ownerId) {
const forwardText = `📩 **Nachricht von ${msg.sender.first_name}** (ID: ${senderId}):\n\n${text}`;
const sentMsg = await bot.api.sendMessageToUser(ownerId, forwardText, { format: 'markdown' });
if (sentMsg && sentMsg.body && sentMsg.body.mid) {
await db.run('INSERT OR REPLACE INTO reply_map (owner_msg_mid, client_user_id) VALUES (?, ?)',
[sentMsg.body.mid, senderId]);
}
return;
}
// Antwortlogik
});
Die mid der gesendeten Nachricht wird in reply_map gespeichert, um sie später für die Weiterleitung nutzen zu können.
Logik für Admin-Antworten
Antwortnachrichten enthalten link.type = 'reply' und link.message.mid – die ID der ursprünglichen Nachricht. Um den Client zu finden:
- Wenn
link.type === 'reply': extrahiererepliedMsgMid, suche in der DB. - Schicke die Antwort zurück an den Client mithilfe von
client_user_id. - Bestätige den Empfang beim Admin.
Beispiel für JSON-Struktur einer Antwort:
{
"body": { "text": "Antwort", ... },
"sender": { ... },
"link": {
"type": "reply",
"message": {
"mid": "mid.original_message..."
}
}
}
Vorteile dieser Architektur
- Lokale Entwicklung: Starten mit
npm start– keine Ports oder SSL-Konfiguration nötig. - Replieschnittstelle: Admins nutzen die Standard-Funktion zum Antworten nahtlos.
- Einfache Datenbank: Eine Datei (
database.sqlite) für einfache Sicherungen. - Skalierbarkeit: Einfache Migration zu PostgreSQL bei steigendem Traffic.
Wichtige Erkenntnisse
- Long Polling vereinfacht die MVP-Entwicklung, da Webhooks entfallen.
- Die SQLite-Tabelle
reply_mapsorgt für präzise Antwortweiterleitung. - Markdown in Weiterleitungen liefert Kontext (Name, ID des Clients).
- Fallback für Admin-Antworten: Falls kein Treffer, wird der zuletzt aktive Client verwendet.
— Editorial Team
Noch keine Kommentare.