Application web de gestion de demandes de livres numériques. Les utilisateurs soumettent des demandes, suivent leur statut et téléchargent leurs livres. Les administrateurs gèrent les demandes, les utilisateurs et les notifications.
🇫🇷 Projet développé par et pour la communauté francophone. Interface, documentation et support entièrement en français.
Si le projet vous est utile, une ⭐ sur GitHub fait toujours plaisir et aide à le faire connaître !
- Frontend — React, React Router, Chart.js, Axios
- Backend — Node.js, Express, MongoDB (Mongoose), JWT
- Notifications — Email (SMTP), Push (VAPID), Apprise
- IA — OpenAI / Ollama (recommandations, descriptions)
- Connecteurs — Valentine (téléchargement auto), Anna's Archive (recherche + téléchargement via FlareSolverr), Calibre-Web (envoi + sync étagère Kobo)
- Déploiement — Docker, GitHub Actions, Docker Hub
Demandes
- Soumission et suivi de demandes de livres
- Recherche via Google Books API avec auto-complétion des métadonnées :
- Par titre ou ISBN — recherche directe ou par code ISBN-10/13
- Par auteur — résultats filtrés en français, triés du plus récent au plus ancien
- Auteur + Titre combinés — saisir
Prénom Nom Titre du livresans séparateur (ex :Virginie Grimaldi D'autres printemps) - Scan de code-barres — scanner l'ISBN directement depuis la caméra de l'appareil
- Vérification de disponibilité à la soumission (flux PreDB)
- Quota de demandes configurable par utilisateur (nombre + fenêtre glissante en jours)
- Soumission admin au nom d'un autre utilisateur
Téléchargement
- Téléchargement automatique via Valentine, avec fallback Anna's Archive
- Recherche manuelle sur les connecteurs depuis le panel admin
- Envoi automatique du fichier vers Calibre-Web à la complétion d'une demande
- Synchronisation automatique de l'étagère Kobo dans Calibre-Web (le livre apparaît directement sur la liseuse)
Utilisateurs & accès
- Inscription par invitation email ou code d'invitation (usage limité, expiration configurable)
- Authentification deux facteurs (2FA — TOTP) avec codes de récupération
- Réinitialisation de mot de passe par email
- Gestion des utilisateurs (rôles, quotas, activation/désactivation)
- Catalogue OPDS pour accès depuis les liseuses (Calibre, KOReader…)
Notifications
- Notifications email et push (VAPID) par événement
- Notifications multi-services via Apprise (Pushover, Discord, Telegram, Slack, Gotify, Ntfy…)
- Côté admin : notifications globales configurables par événement (nouvelle demande, complétion, annulation, commentaire, signalement, nouvel utilisateur)
- Côté utilisateur : chaque utilisateur peut configurer ses propres URLs Apprise dans ses paramètres pour recevoir ses notifications personnelles (livre disponible, annulation, commentaire admin)
- Diffusion admin (email HTML + push vers tous les utilisateurs)
Découverte & IA
- Bibliothèque personnelle avec statut de lecture et notation
- Page Découverte (tendances, bestsellers, recommandations IA)
Administration
- Panel admin avec statistiques et logs
- Visionneuse de logs système en temps réel
- Docker et Docker Compose
- Une instance MongoDB — MongoDB Atlas (cloud, gratuit en tier M0) ou une instance locale
L'image est disponible publiquement sur Docker Hub :
zlimteck/ebookrequest:latest
👉 hub.docker.com/r/zlimteck/ebookrequest
Un docker-compose.yml est fourni à la racine du projet. Il inclut le conteneur principal ebookrequest ainsi que FlareSolverr (nécessaire pour Anna's Archive) :
services:
ebookrequest:
image: zlimteck/ebookrequest:latest
container_name: ebookrequest
restart: always
ports:
- "${PORT:-5001}:5001"
volumes:
- ${UPLOADS_PATH}:/app/uploads
environment:
- NODE_ENV=production
- MONGODB_URI=${MONGODB_URI}
- JWT_SECRET=${JWT_SECRET}
- FRONTEND_URL=${FRONTEND_URL}
# ... (voir .env.example pour la liste complète)
extra_hosts:
- "host.docker.internal:host-gateway"
flaresolverr:
image: ghcr.io/flaresolverr/flaresolverr:latest
container_name: flaresolverr
restart: unless-stopped
ports:
- "8191:8191"Les variables d'environnement sont lues depuis le fichier
.envplacé au même niveau quedocker-compose.yml.
FlareSolverr est inclus dans le
docker-compose.ymlet démarré automatiquement. Il est nécessaire pour contourner la protection Cloudflare d'Anna's Archive lors des téléchargements automatiques. Sans lui, le connecteur Anna's Archive ne fonctionnera pas. L'URL est préconfigurée àhttp://flaresolverr:8191— aucune configuration supplémentaire n'est requise si tu utilises ledocker-compose.ymlfourni.
Copie .env.example en .env et remplis les valeurs :
cp .env.example .env| Variable | Description |
|---|---|
NODE_ENV |
production ou development |
PORT |
Port du backend (défaut : 5001) |
MONGODB_URI |
URI de connexion MongoDB (Atlas ou local) |
JWT_SECRET |
Clé secrète pour signer les tokens JWT — choisir une valeur longue et aléatoire |
UPLOADS_PATH |
Chemin absolu du dossier de stockage des fichiers uploadés |
| Variable | Description |
|---|---|
FRONTEND_URL |
URL publique de l'application (ex : https://ebook.tondomaine.fr). Utilisée pour les liens dans les emails (vérification, reset mot de passe, invitations) et la configuration CORS en production. Obligatoire en production. |
REACT_APP_API_URL |
URL du backend utilisée par le frontend au moment du build (ex : https://ebook.tondomaine.fr). Nécessaire uniquement si le frontend et le backend sont sur des origines différentes. En monorepo (frontend servi par le backend), laisser vide — les requêtes sont alors relatives (/api/...). |
| Variable | Description |
|---|---|
EMAIL_PROVIDER |
smtp (défaut) ou resend |
SMTP_HOST |
Adresse du serveur SMTP (ex : smtp.gmail.com) |
SMTP_PORT |
Port SMTP — 587 pour STARTTLS, 465 pour SSL/TLS |
SMTP_SECURE |
false avec le port 587 (STARTTLS), true avec le port 465 (SSL) — ne pas mélanger |
SMTP_USER |
Identifiant de connexion SMTP |
SMTP_PASSWORD |
Mot de passe SMTP |
EMAIL_FROM_ADDRESS |
Adresse expéditrice des emails |
EMAIL_FROM_NAME |
Nom affiché dans les emails (ex : EbookRequest) |
RESEND_API_KEY |
Clé API Resend (si EMAIL_PROVIDER=resend) |
RESEND_WEBHOOK_SECRET |
Secret de signature webhook Resend (optionnel, recommandé) |
| Variable | Description |
|---|---|
VAPID_PUBLIC_KEY |
Clé publique VAPID |
VAPID_PRIVATE_KEY |
Clé privée VAPID |
Générer les clés VAPID :
npx web-push generate-vapid-keys| Variable | Description |
|---|---|
AI_PROVIDER |
openai ou ollama |
OPENAI_API_KEY |
Clé API OpenAI (si AI_PROVIDER=openai) |
OPENAI_MODEL |
Modèle OpenAI à utiliser (ex : gpt-4o-mini) |
OLLAMA_URL |
URL du serveur Ollama (si AI_PROVIDER=ollama, ex : http://172.17.0.x:11434) |
OLLAMA_MODEL |
Nom du modèle Ollama |
OLLAMA_TIMEOUT |
Timeout en ms pour les requêtes Ollama (défaut : 60000) |
| Variable | Description |
|---|---|
GOOGLE_BOOKS_API_KEY |
Clé API Google Books (recherche et métadonnées) |
APPRISE_URL |
URL du service Apprise pour les notifications. Par défaut http://apprise:8000 (conteneur inclus dans le docker-compose.yml). Supprimer le service apprise du compose si vous hébergez déjà Apprise ailleurs, et renseigner son URL ici. Ne pas ajouter /notify — le chemin est ajouté automatiquement. Voir github.com/caronc/apprise-api. |
APPRISE_CONFIG_PATH |
Chemin local vers le dossier de configuration Apprise (défaut : ./apprise-config). Nécessaire si APPRISE_STATEFUL_MODE=simple est activé sur le conteneur Apprise. |
TZ |
Fuseau horaire des conteneurs (ex : Europe/Paris). Utile pour que les logs s'affichent à la bonne heure. |
FLARESOLVERR_URL |
URL du service FlareSolverr pour contourner les protections Cloudflare (défaut : http://flaresolverr:8191) |
RSS_FEED_URL |
URL du flux RSS (PreDB) utilisé pour vérifier si un livre est récemment sorti et estimer sa disponibilité au moment de la demande (défaut : https://predb.me/?cats=books-ebooks&rss=1) |
Le service apprise inclus dans le docker-compose.yml utilise une configuration de base. Voici les variables d'environnement utiles à ajouter directement sur le service apprise selon vos besoins :
| Variable | Description |
|---|---|
APPRISE_STATEFUL_MODE=simple |
Active la persistance des configurations Apprise dans un fichier. Sans ça, les URLs configurées sont perdues au redémarrage du conteneur. Recommandé si vous utilisez le panel de configuration d'Apprise. |
APPRISE_ADMIN=y |
Active l'interface d'administration web d'Apprise (accessible sur le port exposé). Permet de gérer les configurations via une UI. |
APPRISE_WORKER_COUNT=1 |
Nombre de workers pour le traitement des notifications. La valeur par défaut peut consommer plus de ressources inutilement sur un petit serveur. |
Exemple de configuration avancée du service apprise :
apprise:
image: caronc/apprise:latest
container_name: apprise
environment:
- APPRISE_STATEFUL_MODE=simple
- APPRISE_WORKER_COUNT=1
- APPRISE_ADMIN=y
- TZ=Europe/Paris
volumes:
- /chemin/vers/apprise/config:/config
ports:
- "8000:8000"
restart: unless-stoppeddocker-compose up -dL'application est accessible sur le port défini dans PORT (défaut : 5001).
L'application écoute sur le port 5001 en HTTP. Pour l'exposer sur un domaine en HTTPS, place un reverse proxy devant (Nginx Proxy Manager, Traefik, Caddy…) qui redirige le trafic HTTPS vers localhost:5001.
Pense à renseigner FRONTEND_URL avec ton URL publique pour que les liens dans les emails fonctionnent correctement.
Au premier lancement, ouvre l'application dans ton navigateur — tu seras redirigé automatiquement vers la page /setup pour créer le compte administrateur.
Pour mettre à jour vers la dernière version :
docker-compose pull
docker-compose up -dLe catalogue OPDS est accessible à l'adresse suivante (pour connecter une liseuse, Calibre, KOReader…) :
http(s)://ton-domaine/opds
Le token d'accès personnel est disponible dans les paramètres du compte utilisateur.
ebookrequest/
├── src/ # Backend Express
│ ├── controllers/
│ ├── middleware/
│ ├── models/
│ ├── routes/
│ ├── scripts/ # initAdmin, migrations
│ ├── services/ # email, push, IA, trending...
│ └── index.js
├── frontend/ # React app
│ ├── public/
│ └── src/
│ ├── components/
│ ├── context/
│ ├── hooks/
│ ├── pages/
│ ├── services/
│ ├── styles/
│ └── utils/
├── .env.example
├── docker-compose.yml
└── Dockerfile
