Cree un canal de alertas sobre el sentimiento de la aplicación que supervise cómo los usuarios hablan sobre su aplicación en la Web, detecte cambios en el sentimiento mediante el análisis de fragmentos de resultados de búsqueda y active alertas cuando el sentimiento negativo aumente o el sentimiento positivo disminuya. Las reseñas de las tiendas de aplicaciones solo capturan una fracción del sentimiento de los usuarios. Los usuarios también discuten aplicaciones en Reddit, revisan blogs, foros y redes sociales. Al buscar el nombre de su aplicación diariamente y analizar el tono de los resultados de búsqueda, podrá detectar los cambios de sentimiento de todas estas fuentes a través de una única API.
Requisitos previos
- Python 3.8+ instalado
- solicita biblioteca instalada
- Una clave API de Scavio de scavio.dev
- Nombres de aplicaciones para monitorear
Guia paso a paso
Paso 1: Definir objetivos de seguimiento
Configure las aplicaciones y consultas de búsqueda utilizadas para el seguimiento de opiniones.
import os, requests, json, datetime
API_KEY = os.environ['SCAVIO_API_KEY']
MONITORED_APPS = [
{'name': 'MyApp', 'queries': ['MyApp review', 'MyApp problems', 'MyApp vs competitor']},
{'name': 'CompetitorApp', 'queries': ['CompetitorApp review', 'CompetitorApp issues']},
]
POSITIVE_WORDS = ['love', 'great', 'excellent', 'best', 'amazing', 'fast', 'reliable', 'smooth', 'perfect', 'recommend']
NEGATIVE_WORDS = ['slow', 'buggy', 'crash', 'terrible', 'worst', 'broken', 'expensive', 'frustrating', 'disappointed', 'awful']
HISTORY_FILE = 'sentiment_history.json'
print(f'Monitoring {len(MONITORED_APPS)} apps')Paso 2: Buscar y recopilar menciones
Busque cada aplicación en Google y Reddit para recopilar menciones actuales.
import time
def collect_mentions(app: dict) -> list:
mentions = []
for query in app['queries']:
for platform in ['google', 'reddit']:
resp = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': API_KEY},
json={'platform': platform, 'query': query}, timeout=15)
results = resp.json().get('organic_results', [])
for r in results[:5]:
mentions.append({
'platform': platform,
'title': r.get('title', ''),
'snippet': r.get('snippet', ''),
'url': r.get('link', ''),
'query': query,
})
time.sleep(0.2)
return mentions
mentions = collect_mentions(MONITORED_APPS[0])
print(f'Collected {len(mentions)} mentions for {MONITORED_APPS[0]["name"]}')Paso 3: Analizar sentimiento
Califique el sentimiento de cada mención según la presencia de palabras positivas y negativas.
def analyze_mention_sentiment(mention: dict) -> dict:
text = (mention.get('title', '') + ' ' + mention.get('snippet', '')).lower()
pos = sum(1 for w in POSITIVE_WORDS if w in text)
neg = sum(1 for w in NEGATIVE_WORDS if w in text)
if pos > neg:
sentiment = 'positive'
elif neg > pos:
sentiment = 'negative'
else:
sentiment = 'neutral'
return {
**mention,
'sentiment': sentiment,
'pos_score': pos,
'neg_score': neg,
}
def batch_sentiment(mentions: list) -> dict:
analyzed = [analyze_mention_sentiment(m) for m in mentions]
pos = sum(1 for a in analyzed if a['sentiment'] == 'positive')
neg = sum(1 for a in analyzed if a['sentiment'] == 'negative')
neutral = sum(1 for a in analyzed if a['sentiment'] == 'neutral')
total = len(analyzed)
return {
'total': total,
'positive': pos,
'negative': neg,
'neutral': neutral,
'sentiment_score': round((pos - neg) / total, 2) if total > 0 else 0,
'mentions': analyzed,
}
result = batch_sentiment(mentions)
print(f"Sentiment: +{result['positive']} -{result['negative']} ={result['neutral']}")
print(f"Score: {result['sentiment_score']}")Paso 4: Detectar cambios de sentimiento
Compare el sentimiento actual con la base histórica para detectar cambios significativos.
def store_sentiment(app_name: str, sentiment: dict):
history = []
try:
with open(HISTORY_FILE) as f:
history = json.load(f)
except FileNotFoundError:
pass
history.append({
'app': app_name,
'date': datetime.date.today().isoformat(),
'score': sentiment['sentiment_score'],
'positive': sentiment['positive'],
'negative': sentiment['negative'],
'total': sentiment['total'],
})
with open(HISTORY_FILE, 'w') as f:
json.dump(history, f, indent=2)
def detect_shift(app_name: str, current_score: float) -> dict:
try:
with open(HISTORY_FILE) as f:
history = json.load(f)
except FileNotFoundError:
return {'shift': 'no_baseline'}
entries = [h for h in history if h['app'] == app_name]
if len(entries) < 3:
return {'shift': 'insufficient_data'}
recent = entries[-5:]
avg = sum(e['score'] for e in recent) / len(recent)
change = current_score - avg
return {
'shift': 'negative' if change < -0.15 else 'positive' if change > 0.15 else 'stable',
'change': round(change, 2),
'baseline_avg': round(avg, 2),
'current': current_score,
}
store_sentiment('MyApp', result)
shift = detect_shift('MyApp', result['sentiment_score'])
print(f"Shift: {shift['shift']} (change: {shift.get('change', 'N/A')})")Paso 5: Generar alertas
Active alertas cuando el sentimiento caiga por debajo del umbral o cambie negativamente.
def check_alerts(apps: list) -> list:
alerts = []
for app in apps:
mentions = collect_mentions(app)
sentiment = batch_sentiment(mentions)
store_sentiment(app['name'], sentiment)
shift = detect_shift(app['name'], sentiment['sentiment_score'])
if shift['shift'] == 'negative':
alert = {
'app': app['name'],
'type': 'sentiment_drop',
'score': sentiment['sentiment_score'],
'change': shift.get('change', 0),
'negative_mentions': [m['title'][:60] for m in sentiment['mentions'] if m['sentiment'] == 'negative'][:3],
}
alerts.append(alert)
print(f"ALERT: {app['name']} sentiment dropped ({shift['change']})")
for m in alert['negative_mentions']:
print(f" - {m}")
else:
print(f"{app['name']}: {shift['shift']} (score: {sentiment['sentiment_score']})")
return alerts
alerts = check_alerts(MONITORED_APPS)Ejemplo en Python
import requests, os
H = {'x-api-key': os.environ['SCAVIO_API_KEY']}
POS = ['love', 'great', 'best', 'fast']
NEG = ['slow', 'buggy', 'crash', 'terrible']
def sentiment(app):
data = requests.post('https://api.scavio.dev/api/v1/search', headers=H,
json={'platform': 'google', 'query': f'{app} review'}).json()
results = data.get('organic_results', [])[:5]
pos = neg = 0
for r in results:
text = (r.get('snippet', '')).lower()
pos += sum(1 for w in POS if w in text)
neg += sum(1 for w in NEG if w in text)
return {'app': app, 'positive': pos, 'negative': neg}
print(sentiment('Slack'))Ejemplo en JavaScript
const H = {'x-api-key': process.env.SCAVIO_API_KEY, 'Content-Type': 'application/json'};
const POS = ['love', 'great', 'best', 'fast'];
const NEG = ['slow', 'buggy', 'crash', 'terrible'];
async function sentiment(app) {
const r = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST', headers: H,
body: JSON.stringify({platform: 'google', query: `${app} review`})
});
const results = (await r.json()).organic_results || [];
let pos = 0, neg = 0;
results.slice(0, 5).forEach(r => {
const t = (r.snippet || '').toLowerCase();
POS.forEach(w => { if (t.includes(w)) pos++; });
NEG.forEach(w => { if (t.includes(w)) neg++; });
});
return {app, positive: pos, negative: neg};
}
sentiment('Slack').then(console.log);Salida esperada
An automated sentiment monitoring pipeline that tracks app mentions across web and Reddit, detects sentiment shifts, and triggers alerts when negative sentiment spikes.