Aperçu
Ce workflow collecte les avis produits et les mentions d'Amazon et Reddit, attribue un score de sentiment de base à chacun, et suit l'évolution du sentiment dans le temps. Il aide les équipes produit à détecter rapidement les problèmes de qualité, à mesurer l'impact des nouvelles versions et à surveiller la réception des produits concurrents sans lecture manuelle des avis.
Déclencheur
Planification Cron (quotidien à 11h UTC)
Planification
S'exécute quotidiennement à 11h UTC
Étapes du workflow
Définir la liste de produits
Charger la liste de vos propres produits et des produits concurrents à suivre depuis la configuration.
Rechercher sur Amazon et Reddit
Appeler l'API Scavio sur les deux plateformes pour chaque produit afin de récupérer les avis et discussions récents.
Extraire le texte des avis
Extraire le corps de l'avis, la note et le texte d'extrait de chaque résultat.
Évaluer le sentiment
Appliquer un évaluateur de sentiment basé sur des mots-clés ou un LLM à chaque avis. Classer comme positif, neutre ou négatif.
Agréger et tendance
Calculer la distribution quotidienne des sentiments et la comparer à la moyenne mobile des 7 derniers jours.
Alerter en cas de changements
Si le sentiment négatif dépasse le seuil ou change significativement, envoyer une alerte à l'équipe produit.
Implémentation Python
import requests
import json
from pathlib import Path
API_KEY = "your_scavio_api_key"
POSITIVE_WORDS = {"great", "love", "excellent", "perfect", "best", "amazing"}
NEGATIVE_WORDS = {"broken", "terrible", "worst", "waste", "awful", "bad", "poor"}
def search_product(query: str, platform: str) -> list[dict]:
res = requests.post(
"https://api.scavio.dev/api/v1/search",
headers={"x-api-key": API_KEY},
json={"platform": platform, "query": f"{query} reviews"},
timeout=15,
)
res.raise_for_status()
return res.json().get("organic", [])
def score_sentiment(text: str) -> str:
words = set(text.lower().split())
pos = len(words & POSITIVE_WORDS)
neg = len(words & NEGATIVE_WORDS)
if pos > neg:
return "positive"
if neg > pos:
return "negative"
return "neutral"
def run():
products = ["your-product-name", "competitor-product"]
results = []
for product in products:
for platform in ["amazon", "reddit"]:
items = search_product(product, platform)
for item in items:
text = item.get("snippet", "") or item.get("title", "")
sentiment = score_sentiment(text)
results.append({
"product": product,
"platform": platform,
"title": item.get("title", ""),
"sentiment": sentiment,
})
counts = {"positive": 0, "neutral": 0, "negative": 0}
for r in results:
counts[r["sentiment"]] += 1
print(f"Tracked {len(results)} mentions")
print(f"Sentiment: {json.dumps(counts)}")
neg_ratio = counts["negative"] / max(len(results), 1)
if neg_ratio > 0.4:
print("ALERT: Negative sentiment exceeds 40% threshold")
if __name__ == "__main__":
run()Implémentation JavaScript
const API_KEY = "your_scavio_api_key";
const POSITIVE = new Set(["great", "love", "excellent", "perfect", "best", "amazing"]);
const NEGATIVE = new Set(["broken", "terrible", "worst", "waste", "awful", "bad", "poor"]);
async function searchProduct(query, platform) {
const res = await fetch("https://api.scavio.dev/api/v1/search", {
method: "POST",
headers: {
"x-api-key": API_KEY,
"content-type": "application/json",
},
body: JSON.stringify({ platform, query: `${query} reviews` }),
});
if (!res.ok) throw new Error(`scavio ${res.status}`);
const data = await res.json();
return data.organic ?? [];
}
function scoreSentiment(text) {
const words = new Set(text.toLowerCase().split(/\s+/));
let pos = 0, neg = 0;
for (const w of words) {
if (POSITIVE.has(w)) pos++;
if (NEGATIVE.has(w)) neg++;
}
if (pos > neg) return "positive";
if (neg > pos) return "negative";
return "neutral";
}
async function run() {
const products = ["your-product-name", "competitor-product"];
const results = [];
for (const product of products) {
for (const platform of ["amazon", "reddit"]) {
const items = await searchProduct(product, platform);
for (const item of items) {
const text = item.snippet ?? item.title ?? "";
results.push({
product,
platform,
title: item.title ?? "",
sentiment: scoreSentiment(text),
});
}
}
}
const counts = { positive: 0, neutral: 0, negative: 0 };
for (const r of results) counts[r.sentiment]++;
console.log(`Tracked ${results.length} mentions`);
console.log("Sentiment:", JSON.stringify(counts));
const negRatio = counts.negative / Math.max(results.length, 1);
if (negRatio > 0.4) {
console.log("ALERT: Negative sentiment exceeds 40% threshold");
}
}
run();Plateformes utilisées
Amazon
Recherche de produits avec prix, notes et avis
Communauté, publications et commentaires imbriqués de n'importe quel subreddit