Files
IT_Ticket_System/app/routes/chatbot.py
T
2026-03-25 11:37:46 -04:00

115 lines
5.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import json
import logging
import requests
from flask import Blueprint, request, jsonify, current_app
from flask_login import login_required, current_user
from app import db
from app.models import Ticket, TicketStatus, TicketPriority, TicketCategory
from app.services.notification_service import notify_new_ticket
from app.services.log_service import log_action
chatbot_bp = Blueprint('chatbot', __name__, url_prefix='/chatbot')
logger = logging.getLogger(__name__)
_SYSTEM_PROMPT = """You are an IT Helpdesk Assistant for an internal IT ticket system.
Your job is to:
1. Help employees report IT issues conversationally.
2. Gather all required information to create a support ticket:
- Issue title (short summary)
- Detailed description
- Category (hardware, software, network, access, email, printer, phone, security, other)
- Priority (low, medium, high, critical)
- Location (optional)
- Asset tag (optional device serial / asset number)
3. When you have enough information, respond with a JSON block like this (and ONLY this, no extra text):
{"action": "create_ticket", "title": "...", "description": "...", "category": "...", "priority": "...", "location": "...", "asset_tag": "..."}
4. For general IT questions, answer helpfully but briefly.
5. If the user seems frustrated or has a critical outage, set priority to "critical".
6. Keep your tone professional, friendly, and concise.
7. Always ask clarifying questions if you need more detail before creating a ticket.
"""
@chatbot_bp.route('/message', methods=['POST'])
@login_required
def chat():
data = request.get_json(force=True)
history = data.get('history', []) # [{role, content}, ...]
user_msg = data.get('message', '').strip()
if not user_msg:
return jsonify({'error': 'Empty message'}), 400
api_key = current_app.config.get('ANTHROPIC_API_KEY', '')
if not api_key:
return jsonify({'reply': "The AI assistant is not configured yet. Please contact your IT administrator.", 'ticket': None})
messages = history + [{'role': 'user', 'content': user_msg}]
try:
resp = requests.post(
'https://api.anthropic.com/v1/messages',
headers={
'x-api-key' : api_key,
'anthropic-version': '2023-06-01',
'content-type' : 'application/json',
},
json={
'model' : 'claude-sonnet-4-20250514',
'max_tokens': 1024,
'system' : _SYSTEM_PROMPT,
'messages' : messages,
},
timeout=30,
)
resp.raise_for_status()
reply_text = resp.json()['content'][0]['text'].strip()
except Exception as exc:
logger.error(f'[CHATBOT API ERROR] {exc}')
return jsonify({'reply': 'Sorry, I encountered an error. Please try again or submit a ticket manually.', 'ticket': None})
# Check if the AI wants to create a ticket
ticket_data = None
if '"action": "create_ticket"' in reply_text or "'action': 'create_ticket'" in reply_text:
try:
start = reply_text.find('{')
end = reply_text.rfind('}') + 1
parsed = json.loads(reply_text[start:end])
if parsed.get('action') == 'create_ticket':
ticket = Ticket(
title = parsed.get('title', 'Untitled Issue'),
description = parsed.get('description', ''),
category = parsed.get('category', TicketCategory.OTHER),
priority = parsed.get('priority', TicketPriority.MEDIUM),
location = parsed.get('location', ''),
asset_tag = parsed.get('asset_tag', ''),
created_by_id = current_user.id,
status = TicketStatus.OPEN,
ai_generated = True,
)
ticket.ticket_number = ticket.generate_ticket_number()
db.session.add(ticket)
db.session.commit()
log_action(current_user.id, 'ticket_create_chatbot', 'ticket', ticket.id,
f'ticket_number={ticket.ticket_number} ai_generated=True')
logger.info(f'[CHATBOT TICKET CREATE] ticket_id={ticket.id} number={ticket.ticket_number} user_id={current_user.id}')
notify_new_ticket(ticket)
ticket_data = {
'id' : ticket.id,
'ticket_number' : ticket.ticket_number,
'title' : ticket.title,
'url' : f'/tickets/{ticket.id}',
}
reply_text = (
f"✅ **Ticket Created!**\n\n"
f"I've submitted your ticket **{ticket.ticket_number}**: _{ticket.title}_\n\n"
f"Our IT team has been notified and will get back to you shortly. "
f"You can track your ticket [here](/tickets/{ticket.id})."
)
except (json.JSONDecodeError, KeyError) as exc:
logger.warning(f'[CHATBOT PARSE ERROR] Could not parse ticket JSON: {exc}')
return jsonify({'reply': reply_text, 'ticket': ticket_data})