v4
This commit is contained in:
parent
5d275d310a
commit
84f67bc019
BIN
core/__pycache__/utils.cpython-311.pyc
Normal file
BIN
core/__pycache__/utils.cpython-311.pyc
Normal file
Binary file not shown.
Binary file not shown.
@ -30,7 +30,7 @@
|
||||
<div class="col-md-4">
|
||||
<div class="card p-4 text-center">
|
||||
<h6 class="text-uppercase text-muted small fw-bold">Today's Messages</h6>
|
||||
<div class="display-4 fw-bold text-coral">0</div>
|
||||
<div class="display-4 fw-bold text-coral">{{ today_messages_count }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
119
core/utils.py
Normal file
119
core/utils.py
Normal file
@ -0,0 +1,119 @@
|
||||
import requests
|
||||
import logging
|
||||
from .models import Fanpage, Flow, Node, Edge, ChatSession, MessageLog
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def send_fb_message(psid, access_token, message_content):
|
||||
"""
|
||||
Sends a message to a Facebook user via the Graph API.
|
||||
message_content: dict matching Facebook's message object (e.g., {"text": "..."})
|
||||
"""
|
||||
url = f"https://graph.facebook.com/v12.0/me/messages?access_token={access_token}"
|
||||
payload = {
|
||||
"recipient": {"id": psid},
|
||||
"message": message_content
|
||||
}
|
||||
try:
|
||||
response = requests.post(url, json=payload)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
except Exception as e:
|
||||
logger.error(f"Error sending message to Facebook: {e}")
|
||||
return None
|
||||
|
||||
def get_next_node(session, message_text):
|
||||
"""
|
||||
Determines the next node in the flow based on user input.
|
||||
"""
|
||||
fanpage = session.fanpage
|
||||
|
||||
if not session.current_node:
|
||||
# Start of conversation: find the default flow and its start node
|
||||
flow = Flow.objects.filter(fanpage=fanpage, is_default=True).first()
|
||||
if not flow:
|
||||
flow = Flow.objects.filter(fanpage=fanpage).first()
|
||||
|
||||
if flow:
|
||||
return Node.objects.filter(flow=flow, is_start_node=True).first()
|
||||
return None
|
||||
|
||||
# We are in an active session, look for a matching edge
|
||||
edges = Edge.objects.filter(source_node=session.current_node)
|
||||
message_text_clean = message_text.strip().lower()
|
||||
|
||||
for edge in edges:
|
||||
if edge.condition.lower() == message_text_clean:
|
||||
return edge.target_node
|
||||
|
||||
# If no matching edge, we might want to stay at the current node or find a global start
|
||||
# For now, let's just return the current node (re-prompting) if it was a text node,
|
||||
# or None if we don't know what to do.
|
||||
return session.current_node
|
||||
|
||||
def handle_webhook_event(data):
|
||||
"""
|
||||
Main entry point for processing Facebook webhook POST data.
|
||||
"""
|
||||
if data.get('object') != 'page':
|
||||
return
|
||||
|
||||
for entry in data.get('entry', []):
|
||||
for messaging_event in entry.get('messaging', []):
|
||||
sender_id = messaging_event.get('sender', {}).get('id')
|
||||
recipient_id = messaging_event.get('recipient', {}).get('id')
|
||||
|
||||
if not sender_id or not recipient_id:
|
||||
continue
|
||||
|
||||
# 1. Identify Fanpage
|
||||
try:
|
||||
fanpage = Fanpage.objects.get(page_id=recipient_id, is_active=True)
|
||||
except Fanpage.DoesNotExist:
|
||||
logger.warning(f"Received event for unknown or inactive Page ID: {recipient_id}")
|
||||
continue
|
||||
|
||||
# 2. Extract Message
|
||||
message_text = ""
|
||||
if 'message' in messaging_event:
|
||||
message_text = messaging_event['message'].get('text', "")
|
||||
elif 'postback' in messaging_event:
|
||||
# Handle button clicks
|
||||
message_text = messaging_event['postback'].get('payload', "")
|
||||
|
||||
if not message_text:
|
||||
continue
|
||||
|
||||
# 3. Get or Create Session
|
||||
session, created = ChatSession.objects.get_or_create(
|
||||
psid=sender_id,
|
||||
fanpage=fanpage
|
||||
)
|
||||
|
||||
# 4. Log User Message
|
||||
MessageLog.objects.create(
|
||||
session=session,
|
||||
sender_type='user',
|
||||
message_text=message_text
|
||||
)
|
||||
|
||||
# 5. Determine Next Node
|
||||
next_node = get_next_node(session, message_text)
|
||||
|
||||
if next_node:
|
||||
# 6. Send Reply
|
||||
# next_node.content is a JSONField, expected to be {"text": "..."} or similar
|
||||
result = send_fb_message(sender_id, fanpage.access_token, next_node.content)
|
||||
|
||||
if result:
|
||||
# 7. Update Session
|
||||
session.current_node = next_node
|
||||
session.save()
|
||||
|
||||
# 8. Log Bot Response
|
||||
bot_text = next_node.content.get('text', '[Non-text message]')
|
||||
MessageLog.objects.create(
|
||||
session=session,
|
||||
sender_type='bot',
|
||||
message_text=bot_text
|
||||
)
|
||||
@ -2,8 +2,10 @@ from django.shortcuts import render, redirect, get_object_or_404
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django.http import HttpResponse
|
||||
from django.utils import timezone
|
||||
import json
|
||||
from .models import Fanpage, Flow, MessageLog, ChatSession
|
||||
from .utils import handle_webhook_event
|
||||
|
||||
def home(request):
|
||||
if request.user.is_authenticated:
|
||||
@ -16,11 +18,16 @@ def dashboard(request):
|
||||
flows = Flow.objects.all()
|
||||
recent_logs = MessageLog.objects.order_by('-timestamp')[:10]
|
||||
|
||||
# Count messages from today
|
||||
today = timezone.now().date()
|
||||
today_messages_count = MessageLog.objects.filter(timestamp__date=today).count()
|
||||
|
||||
context = {
|
||||
'fanpage_count': fanpages.count(),
|
||||
'flow_count': flows.count(),
|
||||
'fanpages': fanpages,
|
||||
'recent_logs': recent_logs,
|
||||
'today_messages_count': today_messages_count,
|
||||
}
|
||||
return render(request, 'core/dashboard.html', context)
|
||||
|
||||
@ -54,10 +61,11 @@ def webhook(request):
|
||||
# Handle incoming messages
|
||||
try:
|
||||
data = json.loads(request.body.decode('utf-8'))
|
||||
# Process the webhook payload here in the future
|
||||
# For now, just return 200 OK
|
||||
# Process the webhook payload
|
||||
handle_webhook_event(data)
|
||||
return HttpResponse('EVENT_RECEIVED')
|
||||
except Exception as e:
|
||||
# Log the error if necessary
|
||||
return HttpResponse('Error processing request', status=400)
|
||||
|
||||
return HttpResponse('Method not allowed', status=405)
|
||||
@ -1,3 +1,4 @@
|
||||
Django==5.2.7
|
||||
mysqlclient==2.2.7
|
||||
python-dotenv==1.1.1
|
||||
requests==2.31.0
|
||||
Loading…
x
Reference in New Issue
Block a user