whatsaap Bot statistics and activity
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
f2180483f0
commit
0b8c403e55
@ -1,5 +1,17 @@
|
|||||||
from django.views.generic.base import TemplateView
|
from django.views.generic.base import TemplateView
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
|
from pxy_whatsapp.views import whatsapp_stats
|
||||||
|
import json
|
||||||
|
import logging
|
||||||
|
from django.contrib.auth.decorators import login_required
|
||||||
|
from pxy_whatsapp.models import WhatsAppBot
|
||||||
|
from django.shortcuts import render
|
||||||
|
from django.utils import timezone
|
||||||
|
from datetime import timedelta
|
||||||
|
import json
|
||||||
|
from pxy_whatsapp.models import Message, WhatsAppBot
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class AppsView(LoginRequiredMixin, TemplateView):
|
class AppsView(LoginRequiredMixin, TemplateView):
|
||||||
@ -270,12 +282,57 @@ def dispatch_plan_view(request):
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
from django.contrib.auth.decorators import login_required
|
|
||||||
from django.shortcuts import render
|
|
||||||
import requests
|
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def apps_whatsapp_bot(request):
|
def apps_whatsapp_bot(request):
|
||||||
stats = request.user.has_perm("pxy_whatsapp.view_whatsappstats") and \
|
stats = {}
|
||||||
requests.get(request.build_absolute_uri("/whatsapp/stats/"), cookies=request.COOKIES).json()
|
bots_info = []
|
||||||
return render(request, "pxy_dashboard/apps/apps-whatsapp-bot.html", {"stats": stats})
|
|
||||||
|
# — 1) Cargar métricas —
|
||||||
|
try:
|
||||||
|
resp = whatsapp_stats(request)
|
||||||
|
if resp.status_code == 200:
|
||||||
|
stats = resp.json()
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error loading WhatsApp stats: {e}")
|
||||||
|
|
||||||
|
# — 2) Cargar información de los bots —
|
||||||
|
try:
|
||||||
|
for bot in WhatsAppBot.objects.all():
|
||||||
|
bots_info.append({
|
||||||
|
"name": bot.name,
|
||||||
|
"phone_number_id": bot.phone_number_id,
|
||||||
|
"is_active": bot.is_active,
|
||||||
|
"assistant": bot.assistant.name,
|
||||||
|
})
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error loading WhatsApp bots: {e}")
|
||||||
|
|
||||||
|
# — 3) Prepare weekly data for scatter —
|
||||||
|
today = timezone.now().date()
|
||||||
|
start_date = today - timedelta(days=6)
|
||||||
|
weekly_data = {}
|
||||||
|
for bot in WhatsAppBot.objects.all():
|
||||||
|
points = []
|
||||||
|
for i in range(7):
|
||||||
|
day = start_date + timedelta(days=i)
|
||||||
|
count = Message.objects.filter(
|
||||||
|
conversation__bot=bot,
|
||||||
|
timestamp__date=day
|
||||||
|
).count()
|
||||||
|
points.append({"x": day.strftime("%Y-%m-%d"), "y": count})
|
||||||
|
weekly_data[bot.name] = points
|
||||||
|
|
||||||
|
# pass it as JSON
|
||||||
|
context = {
|
||||||
|
"stats": stats,
|
||||||
|
"bots_info": bots_info,
|
||||||
|
"weekly_data_json": json.dumps(weekly_data),
|
||||||
|
}
|
||||||
|
|
||||||
|
return render(request, "pxy_dashboard/apps/apps-whatsapp-bot.html", context)
|
||||||
|
|
||||||
|
@ -1,12 +1,21 @@
|
|||||||
{% extends "pxy_dashboard/partials/base.html" %}
|
{% extends "pxy_dashboard/partials/base.html" %}
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
{% block title %}Zone Definition{% endblock %}
|
||||||
|
|
||||||
|
{% block extra_css %}
|
||||||
|
<link rel="stylesheet" href="{% static 'dashboard/vendor/apexcharts/apexcharts.css' %}">
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% include "pxy_dashboard/partials/dashboard/kpi_row.html" %}
|
{% include "pxy_dashboard/partials/dashboard/kpi_row.html" %}
|
||||||
|
|
||||||
|
|
||||||
<div class="row mb-4">
|
<div class="row mb-4">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="card text-center">
|
<div class="card text-center">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h3>{{ stats.total_conversations }}</h3>
|
<h3>{{ stats.total_conversations|default:"–" }}</h3>
|
||||||
<p>Conversaciones totales</p>
|
<p>Conversaciones totales</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -14,7 +23,7 @@
|
|||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="card text-center">
|
<div class="card text-center">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h3>{{ stats.messages_in }}</h3>
|
<h3>{{ stats.messages_in|default:"–" }}</h3>
|
||||||
<p>Mensajes recibidos (24h)</p>
|
<p>Mensajes recibidos (24h)</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -22,7 +31,7 @@
|
|||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="card text-center">
|
<div class="card text-center">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h3>{{ stats.messages_out }}</h3>
|
<h3>{{ stats.messages_out|default:"–" }}</h3>
|
||||||
<p>Mensajes enviados (24h)</p>
|
<p>Mensajes enviados (24h)</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -30,26 +39,104 @@
|
|||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="card text-center">
|
<div class="card text-center">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h3>{{ stats.avg_response_time|floatformat:0 }} ms</h3>
|
<h3>{{ stats.avg_response_time|default:"–" }} ms</h3>
|
||||||
<p>Tiempo de respuesta promedio</p>
|
<p>Tiempo de respuesta promedio</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card">
|
<!-- Bots Configurados -->
|
||||||
<div class="card-header"><h5>Actividad por hora</h5></div>
|
<div class="card mb-4">
|
||||||
|
<div class="card-header">
|
||||||
|
<h5 class="mb-0">Bots Configurados</h5>
|
||||||
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div id="chart-whatsapp-activity" class="apex-charts"></div>
|
<div class="table-responsive">
|
||||||
|
<table class="table table-hover mb-0">
|
||||||
|
<thead class="table-light">
|
||||||
|
<tr>
|
||||||
|
<th>Nombre</th>
|
||||||
|
<th>Phone Number ID</th>
|
||||||
|
<th>Estado</th>
|
||||||
|
<th>Asistente AI</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for bot in bots_info %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ bot.name }}</td>
|
||||||
|
<td>{{ bot.phone_number_id }}</td>
|
||||||
|
<td>
|
||||||
|
{% if bot.is_active %}
|
||||||
|
<span class="badge bg-success">Activo</span>
|
||||||
|
{% else %}
|
||||||
|
<span class="badge bg-secondary">Inactivo</span>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td>{{ bot.assistant }}</td>
|
||||||
|
</tr>
|
||||||
|
{% empty %}
|
||||||
|
<tr>
|
||||||
|
<td colspan="4" class="text-center text-muted">
|
||||||
|
No hay bots configurados
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% block extra_js %}
|
<!-- Weekly Activity Scatter -->
|
||||||
<script src="{% static 'dashboard/vendor/apexcharts/apexcharts.min.js' %}"></script>
|
<div class="card mb-4">
|
||||||
<script>
|
<div class="card-header">
|
||||||
// Aquí harías un fetch("/whatsapp/activity/") para datos por hora
|
<h5 class="mb-0">Actividad Semanal de Mensajes por Bot</h5>
|
||||||
// y luego construyes un gráfico de barras/apexcharts como en Route Optimization
|
</div>
|
||||||
</script>
|
<div class="card-body">
|
||||||
{% endblock %}
|
<div id="chart-bots-weekly" class="apex-charts" data-colors="#727cf5,#0acf97,#fa5c7c"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block extra_js %}
|
||||||
|
<!-- Carga ApexCharts -->
|
||||||
|
<script src="{% static 'dashboard/vendor/apexcharts/apexcharts.min.js' %}"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Datos semanales pasados desde la vista
|
||||||
|
const weeklyData = {{ weekly_data_json|safe }};
|
||||||
|
|
||||||
|
// Preparamos series para ApexCharts
|
||||||
|
const series = Object.entries(weeklyData).map(([name, data]) => ({
|
||||||
|
name,
|
||||||
|
data
|
||||||
|
}));
|
||||||
|
|
||||||
|
new ApexCharts(document.querySelector("#chart-bots-weekly"), {
|
||||||
|
chart: {
|
||||||
|
type: 'scatter',
|
||||||
|
height: 350,
|
||||||
|
zoom: { enabled: true }
|
||||||
|
},
|
||||||
|
series,
|
||||||
|
xaxis: {
|
||||||
|
type: 'category',
|
||||||
|
title: { text: 'Fecha' }
|
||||||
|
},
|
||||||
|
yaxis: {
|
||||||
|
title: { text: 'Número de Mensajes' }
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
x: { show: true, formatter: val => val }
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
text: 'Actividad de Mensajes por Bot (últimos 7 días)'
|
||||||
|
}
|
||||||
|
}).render();
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
@ -4,4 +4,5 @@ from . import views
|
|||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('webhook/', views.webhook, name='webhook'),
|
path('webhook/', views.webhook, name='webhook'),
|
||||||
path('webhook/verify/', views.webhook_verification, name='webhook_verification'),
|
path('webhook/verify/', views.webhook_verification, name='webhook_verification'),
|
||||||
|
path('stats/', views.whatsapp_stats, name='whatsapp_stats'),
|
||||||
]
|
]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user