Créer un bot de feedback MVP pour Max.ru avec le polling long et SQLite
Max.ru offre aux développeurs un accès à son API Bot pour créer des outils interactifs. Pour ce bot MVP de retour d’expérience, nous utilisons Node.js avec la bibliothèque @maxhub/max-bot-api et SQLite. Le polling long permet un développement local sans nécessiter de webhooks, de serveurs ou de HTTPS.
Le défi principal consiste à identifier le client lorsqu’un administrateur répond. Les messages de réponse contiennent un lien avec l’ID du message original (mid), ce qui nous permet de remonter la réponse à l’utilisateur via la base de données.
Choix de la stack technique et configuration du projet
La bibliothèque @maxhub/max-bot-api prend en charge nativement le polling long, éliminant tout besoin d’outils comme ngrok ou Cloudflare Tunnel pendant le développement.
SQLite est idéal pour un MVP : c’est une base de données basée sur fichier, sans serveur séparé, avec une latence minimale et une gestion cohérente des requêtes.
Installez les dépendances :
npm init -y
npm install @maxhub/max-bot-api sqlite sqlite3 dotenv
Créez un fichier .env :
BOT_TOKEN=your_token_here
OWNER_ID=12345678
Le jeton est généré dans business.max.ru, et OWNER_ID correspond à votre identifiant utilisateur Max personnel.
Initialisation de SQLite et structure de la base de données
Utilisez une connexion asynchrone et créez la table reply_map pour le mappage :
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('Base de données prête');
})();
Cette table stocke le mappage entre owner_msg_mid et client_user_id.
Gestion des messages des clients
L’événement message_created vérifie l’expéditeur. Les messages clients sont transférés à l’administrateur avec une mise en forme Markdown :
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 = `📩 **Message de ${msg.sender.first_name}** (ID: ${senderId}) :
${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;
}
// logique de réponse
});
L’ID du message envoyé est stocké dans reply_map pour un routage ultérieur.
Logique de réponse de l’administrateur
Les messages de réponse contiennent link.type = 'reply' et link.message.mid — l’ID du message original. Pour retrouver le client :
- Si
link.type === 'reply': extrayezrepliedMsgMid, interrogez la base de données. - Envoyez la réponse au client via
client_user_id. - Confirmez la réception à l’administrateur.
Structure JSON d’exemple pour une réponse :
{
"body": { "text": "réponse", ... },
"sender": { ... },
"link": {
"type": "reply",
"message": {
"mid": "mid.message_originale..."
}
}
}
Avantages de cette architecture
- Développement local : lancez avec
npm start— pas besoin de configurer de ports ou de SSL. - Interface de réponse naturelle : les administrateurs utilisent la fonction standard de réponse sans interruption.
- Base de données simple : un seul fichier (
database.sqlite) pour des sauvegardes faciles. - Évolutivité : migration aisée vers PostgreSQL à mesure que le trafic augmente.
Points clés à retenir
- Le polling long simplifie le développement MVP en supprimant la nécessité de webhooks.
- La table
reply_mapde SQLite garantit un routage précis des réponses. - L’utilisation du Markdown dans les messages transférés ajoute du contexte (nom du client, ID).
- Mécanisme de secours : si aucun correspondant n’est trouvé, on utilise le dernier client actif.
— Editorial Team
Aucun commentaire pour le moment.