This repository has been archived on 2025-08-07. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
suppdonn-tracker/server.js
2025-02-27 14:28:08 +01:00

225 lines
8.4 KiB
JavaScript

// server.js
const express = require('express');
const axios = require('axios');
const path = require('path');
const app = express();
const port = process.env.PORT || 3000;
// Servir les fichiers statiques
app.use(express.static('public'));
// Route pour vérifier que le serveur fonctionne
app.get('/api/health', (req, res) => {
res.json({ status: 'ok', time: new Date().toISOString() });
});
// Route principale pour extraire les données d'une campagne Ulule
app.get('/api/ulule/:slug', async (req, res) => {
try {
const { slug } = req.params;
console.log(`Récupération des données pour la campagne: ${slug}`);
// Utiliser directement l'API publique d'Ulule
const apiUrl = `https://api.ulule.com/v1/projects/${slug}`;
console.log(`Tentative d'accès à l'API: ${apiUrl}`);
const response = await axios.get(apiUrl, {
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
'Accept': 'application/json',
'Cache-Control': 'no-cache'
},
timeout: 10000
});
// Vérifier si la réponse est valide
if (response.status === 200 && response.data) {
console.log("Données récupérées avec succès depuis l'API d'Ulule");
const projectData = response.data;
// Formater les données pour notre application
const formattedData = {
name: projectData.name ?
(projectData.name.fr || projectData.name.en || Object.values(projectData.name)[0]) :
slug,
amount_raised: projectData.amount_raised || 0,
goal: projectData.goal || 0,
currency: projectData.currency || "EUR",
supporters_count: projectData.supporters_count || 0,
days_left: 0,
percent: projectData.percent || 0,
success: true,
source: 'api'
};
// Calculer les jours restants
if (projectData.date_end) {
const endDate = new Date(projectData.date_end);
const now = new Date();
const diffTime = endDate - now;
formattedData.days_left = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
}
return res.json(formattedData);
} else {
throw new Error(`Réponse invalide de l'API: ${response.status}`);
}
} catch (error) {
console.error('Erreur lors de la récupération des données:', error.message);
// En cas d'erreur, renvoyer des données de démonstration
res.json({
name: req.params.slug,
amount_raised: 5000,
goal: 10000,
currency: "EUR",
supporters_count: 42,
days_left: 15,
percent: 50,
success: false,
source: 'error',
error: error.message,
message: "Données de démonstration en raison d'une erreur"
});
}
});
// Route pour récupérer les détails des récompenses d'une campagne
app.get('/api/ulule/:slug/rewards', async (req, res) => {
try {
const { slug } = req.params;
console.log(`Récupération des récompenses pour la campagne: ${slug}`);
// Utiliser l'API Ulule
const apiUrl = `https://api.ulule.com/v1/projects/${slug}`;
const response = await axios.get(apiUrl);
if (response.status === 200 && response.data && response.data.rewards) {
console.log(`${response.data.rewards.length} récompenses récupérées`);
// Simplifier les données des récompenses
const rewards = response.data.rewards.map(reward => ({
id: reward.id,
title: reward.title ? (reward.title.fr || reward.title.en || Object.values(reward.title)[0]) : '',
price: reward.price,
description: reward.description ? (reward.description.fr || reward.description.en || Object.values(reward.description)[0]) : '',
stock: reward.stock,
stock_available: reward.stock_available,
orders_count: reward.orders_count,
date_delivery: reward.date_delivery
}));
return res.json({ rewards });
} else {
throw new Error(`Aucune récompense trouvée pour la campagne ${slug}`);
}
} catch (error) {
console.error('Erreur lors de la récupération des récompenses:', error.message);
return res.json({ rewards: [] });
}
});
// Route pour récupérer les contributeurs d'une campagne
app.get('/api/ulule/:slug/supporters', async (req, res) => {
try {
const { slug } = req.params;
console.log(`Récupération des contributeurs pour la campagne: ${slug}`);
// Utiliser l'API Ulule pour récupérer les contributeurs avec des champs supplémentaires
const apiUrl = `https://api.ulule.com/v1/projects/${slug}/supporters?extra_fields=latest_project_order,latest_project_comment`;
console.log(`Tentative d'accès à l'API des supporters: ${apiUrl}`);
const response = await axios.get(apiUrl, {
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
'Accept': 'application/json',
'Cache-Control': 'no-cache'
},
timeout: 10000
});
if (response.status === 200 && response.data && response.data.supporters) {
console.log(`${response.data.supporters.length} contributeurs récupérés`);
// Formater les données des contributeurs
const contributors = response.data.supporters.map(supporter => {
// Récupérer le nom complet ou le nom d'utilisateur
let name = supporter.screenname || supporter.name || 'Contributeur anonyme';
// Extraire les informations de commande si disponibles
let reward = '';
let amount = 0;
let comment = '';
if (supporter.latest_project_order && supporter.latest_project_order.items && supporter.latest_project_order.items.length > 0) {
// Récupérer la première récompense
const firstItem = supporter.latest_project_order.items[0];
amount = firstItem.line_total || firstItem.unit_price || 0;
// Récupérer le titre de la récompense
if (firstItem.reward && firstItem.reward.parent && firstItem.reward.parent.title) {
const titles = firstItem.reward.parent.title;
reward = titles.fr || titles.en || Object.values(titles)[0] || '';
// Si c'est une variante, ajouter sa description
if (firstItem.reward.description_fr) {
reward += ` (${firstItem.reward.description_fr})`;
}
}
// Ajouter un pourboire si présent
if (supporter.latest_project_order.tip && supporter.latest_project_order.tip > 0) {
amount += supporter.latest_project_order.tip;
}
}
// Récupérer le commentaire si disponible
if (supporter.latest_project_comment && supporter.latest_project_comment.comment) {
comment = supporter.latest_project_comment.comment;
}
return {
id: supporter.id,
name: name,
reward: reward,
amount: amount,
avatar: supporter.avatar ? (supporter.avatar['90'] || '') : '',
date_joined: supporter.date_joined,
comment: comment,
location: supporter.location || ''
};
});
return res.json({ contributors });
} else {
throw new Error(`Erreur lors de la récupération des contributeurs: ${response.status}`);
}
} catch (error) {
console.error('Erreur lors de la récupération des contributeurs:', error.message);
// En cas d'erreur, renvoyer des données de démonstration
return res.json({
contributors: [
{ name: "Contributeur 1", reward: "Pack Tour", amount: 40, avatar: "", comment: "Super projet!" },
{ name: "Contributeur 2", reward: "Pack Cavalier", amount: 26, avatar: "", comment: "" },
{ name: "Contributeur 3", reward: "Pack Roi", amount: 75, avatar: "", comment: "J'adore!" },
{ name: "Contributeur 4", reward: "Pack Tour", amount: 40, avatar: "", comment: "" },
{ name: "Contributeur 5", reward: "Pack Pion", amount: 6, avatar: "", comment: "" }
]
});
}
});
// Page d'accueil
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'public', 'index.html'));
});
// Démarrer le serveur
app.listen(port, '0.0.0.0', () => {
console.log(`Serveur démarré sur http://0.0.0.0:${port}`);
});