mirror of
https://github.com/aljazceru/enclava.git
synced 2025-12-17 23:44:24 +01:00
zammad working
This commit is contained in:
664
backend/app/api/v1/zammad.py
Normal file
664
backend/app/api/v1/zammad.py
Normal file
@@ -0,0 +1,664 @@
|
||||
"""
|
||||
Zammad Integration API endpoints
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
from typing import Dict, Any, List, Optional
|
||||
from fastapi import APIRouter, Depends, HTTPException, BackgroundTasks
|
||||
from pydantic import BaseModel, validator
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import select, and_, or_, desc
|
||||
from datetime import datetime
|
||||
|
||||
from app.db.database import get_db
|
||||
from app.core.logging import log_api_request
|
||||
from app.services.module_manager import module_manager
|
||||
from app.core.security import get_current_user
|
||||
from app.models.user import User
|
||||
from app.services.api_key_auth import get_api_key_auth
|
||||
from app.models.api_key import APIKey
|
||||
from app.models.chatbot import ChatbotInstance
|
||||
|
||||
# Import Zammad models
|
||||
from modules.zammad.models import (
|
||||
ZammadTicket,
|
||||
ZammadProcessingLog,
|
||||
ZammadConfiguration,
|
||||
ProcessingStatus
|
||||
)
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
class ZammadConfigurationRequest(BaseModel):
|
||||
"""Request model for creating/updating Zammad configuration"""
|
||||
name: str
|
||||
description: Optional[str] = None
|
||||
is_default: bool = False
|
||||
zammad_url: str
|
||||
api_token: str
|
||||
chatbot_id: str
|
||||
process_state: str = "open"
|
||||
max_tickets: int = 10
|
||||
skip_existing: bool = True
|
||||
auto_process: bool = False
|
||||
process_interval: int = 30
|
||||
summary_template: Optional[str] = None
|
||||
custom_settings: Optional[Dict[str, Any]] = {}
|
||||
|
||||
@validator('zammad_url')
|
||||
def validate_zammad_url(cls, v):
|
||||
if not v.startswith(('http://', 'https://')):
|
||||
raise ValueError('Zammad URL must start with http:// or https://')
|
||||
return v.rstrip('/')
|
||||
|
||||
@validator('max_tickets')
|
||||
def validate_max_tickets(cls, v):
|
||||
if not 1 <= v <= 100:
|
||||
raise ValueError('max_tickets must be between 1 and 100')
|
||||
return v
|
||||
|
||||
@validator('process_interval')
|
||||
def validate_process_interval(cls, v):
|
||||
if not 5 <= v <= 1440:
|
||||
raise ValueError('process_interval must be between 5 and 1440 minutes')
|
||||
return v
|
||||
|
||||
|
||||
class ProcessTicketsRequest(BaseModel):
|
||||
"""Request model for processing tickets"""
|
||||
config_id: Optional[int] = None
|
||||
filters: Dict[str, Any] = {}
|
||||
|
||||
@validator('filters', pre=True)
|
||||
def validate_filters(cls, v):
|
||||
"""Ensure filters is always a dict"""
|
||||
if v is None:
|
||||
return {}
|
||||
if isinstance(v, list):
|
||||
# If someone passes a list, convert to empty dict
|
||||
return {}
|
||||
if not isinstance(v, dict):
|
||||
# If it's some other type, convert to empty dict
|
||||
return {}
|
||||
return v
|
||||
|
||||
|
||||
class ProcessSingleTicketRequest(BaseModel):
|
||||
"""Request model for processing a single ticket"""
|
||||
ticket_id: int
|
||||
config_id: Optional[int] = None
|
||||
|
||||
|
||||
class TestConnectionRequest(BaseModel):
|
||||
"""Request model for testing Zammad connection"""
|
||||
zammad_url: str
|
||||
api_token: str
|
||||
|
||||
|
||||
@router.get("/configurations")
|
||||
async def get_configurations(
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""Get all Zammad configurations for the current user"""
|
||||
user_id = current_user.get("id") if isinstance(current_user, dict) else current_user.id
|
||||
|
||||
try:
|
||||
# Get configurations from database
|
||||
stmt = (
|
||||
select(ZammadConfiguration)
|
||||
.where(ZammadConfiguration.user_id == user_id)
|
||||
.where(ZammadConfiguration.is_active == True)
|
||||
.order_by(ZammadConfiguration.is_default.desc(), ZammadConfiguration.created_at.desc())
|
||||
)
|
||||
result = await db.execute(stmt)
|
||||
configurations = [config.to_dict() for config in result.scalars()]
|
||||
|
||||
return {
|
||||
"configurations": configurations,
|
||||
"count": len(configurations)
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Error fetching configurations: {str(e)}")
|
||||
|
||||
|
||||
@router.post("/configurations")
|
||||
async def create_configuration(
|
||||
config_request: ZammadConfigurationRequest,
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""Create a new Zammad configuration"""
|
||||
user_id = current_user.get("id") if isinstance(current_user, dict) else current_user.id
|
||||
|
||||
try:
|
||||
# Verify chatbot exists and user has access
|
||||
chatbot_stmt = select(ChatbotInstance).where(
|
||||
and_(
|
||||
ChatbotInstance.id == config_request.chatbot_id,
|
||||
ChatbotInstance.created_by == str(user_id),
|
||||
ChatbotInstance.is_active == True
|
||||
)
|
||||
)
|
||||
chatbot = await db.scalar(chatbot_stmt)
|
||||
if not chatbot:
|
||||
raise HTTPException(status_code=404, detail="Chatbot not found or access denied")
|
||||
|
||||
# Use the module to handle configuration creation
|
||||
zammad_module = module_manager.get_module("zammad")
|
||||
if not zammad_module:
|
||||
raise HTTPException(status_code=503, detail="Zammad module not available")
|
||||
|
||||
request_data = {
|
||||
"action": "save_configuration",
|
||||
"configuration": config_request.dict()
|
||||
}
|
||||
|
||||
context = {
|
||||
"user_id": user_id,
|
||||
"user_permissions": current_user.get("permissions", [])
|
||||
}
|
||||
|
||||
result = await zammad_module.execute_with_interceptors(request_data, context)
|
||||
|
||||
return result
|
||||
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Error creating configuration: {str(e)}")
|
||||
|
||||
|
||||
@router.put("/configurations/{config_id}")
|
||||
async def update_configuration(
|
||||
config_id: int,
|
||||
config_request: ZammadConfigurationRequest,
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""Update an existing Zammad configuration"""
|
||||
user_id = current_user.get("id") if isinstance(current_user, dict) else current_user.id
|
||||
|
||||
try:
|
||||
# Check if configuration exists and belongs to user
|
||||
stmt = select(ZammadConfiguration).where(
|
||||
and_(
|
||||
ZammadConfiguration.id == config_id,
|
||||
ZammadConfiguration.user_id == user_id
|
||||
)
|
||||
)
|
||||
existing_config = await db.scalar(stmt)
|
||||
if not existing_config:
|
||||
raise HTTPException(status_code=404, detail="Configuration not found")
|
||||
|
||||
# Verify chatbot exists and user has access
|
||||
chatbot_stmt = select(ChatbotInstance).where(
|
||||
and_(
|
||||
ChatbotInstance.id == config_request.chatbot_id,
|
||||
ChatbotInstance.created_by == str(user_id),
|
||||
ChatbotInstance.is_active == True
|
||||
)
|
||||
)
|
||||
chatbot = await db.scalar(chatbot_stmt)
|
||||
if not chatbot:
|
||||
raise HTTPException(status_code=404, detail="Chatbot not found or access denied")
|
||||
|
||||
# Deactivate old configuration and create new one (for audit trail)
|
||||
existing_config.is_active = False
|
||||
|
||||
# Use the module to handle configuration creation
|
||||
zammad_module = module_manager.get_module("zammad")
|
||||
if not zammad_module:
|
||||
raise HTTPException(status_code=503, detail="Zammad module not available")
|
||||
|
||||
request_data = {
|
||||
"action": "save_configuration",
|
||||
"configuration": config_request.dict()
|
||||
}
|
||||
|
||||
context = {
|
||||
"user_id": user_id,
|
||||
"user_permissions": current_user.get("permissions", [])
|
||||
}
|
||||
|
||||
result = await zammad_module.execute_with_interceptors(request_data, context)
|
||||
|
||||
await db.commit()
|
||||
return result
|
||||
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Error updating configuration: {str(e)}")
|
||||
|
||||
|
||||
@router.delete("/configurations/{config_id}")
|
||||
async def delete_configuration(
|
||||
config_id: int,
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""Delete (deactivate) a Zammad configuration"""
|
||||
user_id = current_user.get("id") if isinstance(current_user, dict) else current_user.id
|
||||
|
||||
try:
|
||||
# Check if configuration exists and belongs to user
|
||||
stmt = select(ZammadConfiguration).where(
|
||||
and_(
|
||||
ZammadConfiguration.id == config_id,
|
||||
ZammadConfiguration.user_id == user_id
|
||||
)
|
||||
)
|
||||
config = await db.scalar(stmt)
|
||||
if not config:
|
||||
raise HTTPException(status_code=404, detail="Configuration not found")
|
||||
|
||||
# Deactivate instead of deleting (for audit trail)
|
||||
config.is_active = False
|
||||
config.updated_at = datetime.utcnow()
|
||||
|
||||
await db.commit()
|
||||
|
||||
return {"message": "Configuration deleted successfully"}
|
||||
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Error deleting configuration: {str(e)}")
|
||||
|
||||
|
||||
@router.post("/test-connection")
|
||||
async def test_connection(
|
||||
test_request: TestConnectionRequest,
|
||||
current_user: User = Depends(get_current_user)
|
||||
):
|
||||
"""Test connection to a Zammad instance"""
|
||||
try:
|
||||
zammad_module = module_manager.get_module("zammad")
|
||||
if not zammad_module:
|
||||
raise HTTPException(status_code=503, detail="Zammad module not available")
|
||||
|
||||
user_id = current_user.get("id") if isinstance(current_user, dict) else current_user.id
|
||||
|
||||
request_data = {
|
||||
"action": "test_connection",
|
||||
"zammad_url": test_request.zammad_url,
|
||||
"api_token": test_request.api_token
|
||||
}
|
||||
|
||||
context = {
|
||||
"user_id": user_id,
|
||||
"user_permissions": current_user.get("permissions", [])
|
||||
}
|
||||
|
||||
result = await zammad_module.execute_with_interceptors(request_data, context)
|
||||
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Error testing connection: {str(e)}")
|
||||
|
||||
|
||||
@router.post("/process")
|
||||
async def process_tickets(
|
||||
process_request: ProcessTicketsRequest,
|
||||
background_tasks: BackgroundTasks,
|
||||
current_user: User = Depends(get_current_user)
|
||||
):
|
||||
"""Process tickets for summarization"""
|
||||
try:
|
||||
zammad_module = module_manager.get_module("zammad")
|
||||
if not zammad_module:
|
||||
raise HTTPException(status_code=503, detail="Zammad module not available")
|
||||
|
||||
user_id = current_user.get("id") if isinstance(current_user, dict) else current_user.id
|
||||
|
||||
# Debug logging to identify the issue
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.info(f"Process request filters type: {type(process_request.filters)}")
|
||||
logger.info(f"Process request filters value: {process_request.filters}")
|
||||
|
||||
# Ensure filters is a dict
|
||||
filters = process_request.filters if process_request.filters is not None else {}
|
||||
if not isinstance(filters, dict):
|
||||
logger.error(f"Filters is not a dict: {type(filters)} = {filters}")
|
||||
filters = {}
|
||||
|
||||
request_data = {
|
||||
"action": "process_tickets",
|
||||
"config_id": process_request.config_id,
|
||||
"filters": filters
|
||||
}
|
||||
|
||||
context = {
|
||||
"user_id": user_id,
|
||||
"user_permissions": current_user.get("permissions", [])
|
||||
}
|
||||
|
||||
# Execute processing in background for large batches
|
||||
if filters.get("limit", 10) > 5:
|
||||
# Start background task
|
||||
background_tasks.add_task(
|
||||
_process_tickets_background,
|
||||
zammad_module,
|
||||
request_data,
|
||||
context
|
||||
)
|
||||
|
||||
return {
|
||||
"message": "Processing started in background",
|
||||
"status": "started"
|
||||
}
|
||||
else:
|
||||
# Process immediately for small batches
|
||||
result = await zammad_module.execute_with_interceptors(request_data, context)
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Error starting ticket processing: {str(e)}")
|
||||
|
||||
|
||||
@router.post("/tickets/{ticket_id}/process")
|
||||
async def process_single_ticket(
|
||||
ticket_id: int,
|
||||
process_request: ProcessSingleTicketRequest,
|
||||
current_user: User = Depends(get_current_user)
|
||||
):
|
||||
"""Process a single ticket for summarization"""
|
||||
try:
|
||||
zammad_module = module_manager.get_module("zammad")
|
||||
if not zammad_module:
|
||||
raise HTTPException(status_code=503, detail="Zammad module not available")
|
||||
|
||||
user_id = current_user.get("id") if isinstance(current_user, dict) else current_user.id
|
||||
|
||||
request_data = {
|
||||
"action": "process_single_ticket",
|
||||
"ticket_id": ticket_id,
|
||||
"config_id": process_request.config_id
|
||||
}
|
||||
|
||||
context = {
|
||||
"user_id": user_id,
|
||||
"user_permissions": current_user.get("permissions", [])
|
||||
}
|
||||
|
||||
result = await zammad_module.execute_with_interceptors(request_data, context)
|
||||
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Error processing ticket: {str(e)}")
|
||||
|
||||
|
||||
@router.get("/tickets/{ticket_id}/summary")
|
||||
async def get_ticket_summary(
|
||||
ticket_id: int,
|
||||
current_user: User = Depends(get_current_user)
|
||||
):
|
||||
"""Get the AI summary for a specific ticket"""
|
||||
try:
|
||||
zammad_module = module_manager.get_module("zammad")
|
||||
if not zammad_module:
|
||||
raise HTTPException(status_code=503, detail="Zammad module not available")
|
||||
|
||||
user_id = current_user.get("id") if isinstance(current_user, dict) else current_user.id
|
||||
|
||||
request_data = {
|
||||
"action": "get_ticket_summary",
|
||||
"ticket_id": ticket_id
|
||||
}
|
||||
|
||||
context = {
|
||||
"user_id": user_id,
|
||||
"user_permissions": current_user.get("permissions", [])
|
||||
}
|
||||
|
||||
result = await zammad_module.execute_with_interceptors(request_data, context)
|
||||
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Error getting ticket summary: {str(e)}")
|
||||
|
||||
|
||||
@router.get("/tickets")
|
||||
async def get_processed_tickets(
|
||||
status: Optional[str] = None,
|
||||
limit: int = 20,
|
||||
offset: int = 0,
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""Get list of processed tickets"""
|
||||
user_id = current_user.get("id") if isinstance(current_user, dict) else current_user.id
|
||||
|
||||
try:
|
||||
# Build query
|
||||
query = select(ZammadTicket).where(ZammadTicket.processed_by_user_id == user_id)
|
||||
|
||||
if status:
|
||||
query = query.where(ZammadTicket.processing_status == status)
|
||||
|
||||
query = query.order_by(desc(ZammadTicket.processed_at))
|
||||
query = query.offset(offset).limit(limit)
|
||||
|
||||
# Execute query
|
||||
result = await db.execute(query)
|
||||
tickets = [ticket.to_dict() for ticket in result.scalars()]
|
||||
|
||||
# Get total count
|
||||
count_query = select(ZammadTicket).where(ZammadTicket.processed_by_user_id == user_id)
|
||||
if status:
|
||||
count_query = count_query.where(ZammadTicket.processing_status == status)
|
||||
|
||||
total_result = await db.execute(count_query)
|
||||
total_count = len(list(total_result.scalars()))
|
||||
|
||||
return {
|
||||
"tickets": tickets,
|
||||
"total": total_count,
|
||||
"limit": limit,
|
||||
"offset": offset
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Error fetching tickets: {str(e)}")
|
||||
|
||||
|
||||
@router.get("/status")
|
||||
async def get_module_status(
|
||||
current_user: User = Depends(get_current_user)
|
||||
):
|
||||
"""Get Zammad module status and statistics"""
|
||||
try:
|
||||
zammad_module = module_manager.get_module("zammad")
|
||||
if not zammad_module:
|
||||
raise HTTPException(status_code=503, detail="Zammad module not available")
|
||||
|
||||
user_id = current_user.get("id") if isinstance(current_user, dict) else current_user.id
|
||||
|
||||
request_data = {
|
||||
"action": "get_status"
|
||||
}
|
||||
|
||||
context = {
|
||||
"user_id": user_id,
|
||||
"user_permissions": current_user.get("permissions", [])
|
||||
}
|
||||
|
||||
result = await zammad_module.execute_with_interceptors(request_data, context)
|
||||
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Error getting module status: {str(e)}")
|
||||
|
||||
|
||||
@router.get("/processing-logs")
|
||||
async def get_processing_logs(
|
||||
limit: int = 10,
|
||||
offset: int = 0,
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""Get processing logs for the current user"""
|
||||
user_id = current_user.get("id") if isinstance(current_user, dict) else current_user.id
|
||||
|
||||
try:
|
||||
# Get processing logs
|
||||
query = (
|
||||
select(ZammadProcessingLog)
|
||||
.where(ZammadProcessingLog.initiated_by_user_id == user_id)
|
||||
.order_by(desc(ZammadProcessingLog.started_at))
|
||||
.offset(offset)
|
||||
.limit(limit)
|
||||
)
|
||||
|
||||
result = await db.execute(query)
|
||||
logs = [log.to_dict() for log in result.scalars()]
|
||||
|
||||
# Get total count
|
||||
count_query = select(ZammadProcessingLog).where(
|
||||
ZammadProcessingLog.initiated_by_user_id == user_id
|
||||
)
|
||||
total_result = await db.execute(count_query)
|
||||
total_count = len(list(total_result.scalars()))
|
||||
|
||||
return {
|
||||
"logs": logs,
|
||||
"total": total_count,
|
||||
"limit": limit,
|
||||
"offset": offset
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Error fetching processing logs: {str(e)}")
|
||||
|
||||
|
||||
@router.get("/chatbots")
|
||||
async def get_available_chatbots(
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""Get list of chatbots available for Zammad integration"""
|
||||
user_id = current_user.get("id") if isinstance(current_user, dict) else current_user.id
|
||||
|
||||
try:
|
||||
# Get user's active chatbots
|
||||
stmt = (
|
||||
select(ChatbotInstance)
|
||||
.where(ChatbotInstance.created_by == str(user_id))
|
||||
.where(ChatbotInstance.is_active == True)
|
||||
.order_by(ChatbotInstance.name)
|
||||
)
|
||||
|
||||
result = await db.execute(stmt)
|
||||
chatbots = []
|
||||
|
||||
for chatbot in result.scalars():
|
||||
# Extract chatbot_type from config JSON or provide default
|
||||
config = chatbot.config or {}
|
||||
chatbot_type = config.get('chatbot_type', 'general')
|
||||
model = config.get('model', 'Unknown')
|
||||
|
||||
chatbots.append({
|
||||
"id": chatbot.id,
|
||||
"name": chatbot.name,
|
||||
"chatbot_type": chatbot_type,
|
||||
"model": model,
|
||||
"description": chatbot.description or ''
|
||||
})
|
||||
|
||||
return {
|
||||
"chatbots": chatbots,
|
||||
"count": len(chatbots)
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Error fetching chatbots: {str(e)}")
|
||||
|
||||
|
||||
async def _process_tickets_background(zammad_module, request_data: Dict[str, Any], context: Dict[str, Any]):
|
||||
"""Background task for processing tickets"""
|
||||
try:
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.info(f"Starting background ticket processing with request_data: {request_data}")
|
||||
logger.info(f"Context: {context}")
|
||||
await zammad_module.execute_with_interceptors(request_data, context)
|
||||
except Exception as e:
|
||||
# Log error but don't raise - this is a background task
|
||||
import logging
|
||||
import traceback
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.error(f"Background ticket processing failed: {e}")
|
||||
logger.error(f"Full traceback: {traceback.format_exc()}")
|
||||
|
||||
|
||||
# API key authentication endpoints (for programmatic access)
|
||||
|
||||
@router.post("/api-key/process", dependencies=[Depends(get_api_key_auth)])
|
||||
async def api_process_tickets(
|
||||
process_request: ProcessTicketsRequest,
|
||||
api_key_context: Dict = Depends(get_api_key_auth)
|
||||
):
|
||||
"""Process tickets using API key authentication"""
|
||||
try:
|
||||
zammad_module = module_manager.get_module("zammad")
|
||||
if not zammad_module:
|
||||
raise HTTPException(status_code=503, detail="Zammad module not available")
|
||||
|
||||
user_id = api_key_context["user_id"]
|
||||
|
||||
request_data = {
|
||||
"action": "process_tickets",
|
||||
"config_id": process_request.config_id,
|
||||
"filters": process_request.filters
|
||||
}
|
||||
|
||||
context = {
|
||||
"user_id": user_id,
|
||||
"api_key_id": api_key_context["api_key_id"],
|
||||
"user_permissions": ["modules:*"] # API keys get full module access
|
||||
}
|
||||
|
||||
result = await zammad_module.execute_with_interceptors(request_data, context)
|
||||
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Error processing tickets: {str(e)}")
|
||||
|
||||
|
||||
@router.get("/api-key/status", dependencies=[Depends(get_api_key_auth)])
|
||||
async def api_get_status(
|
||||
api_key_context: Dict = Depends(get_api_key_auth)
|
||||
):
|
||||
"""Get module status using API key authentication"""
|
||||
try:
|
||||
zammad_module = module_manager.get_module("zammad")
|
||||
if not zammad_module:
|
||||
raise HTTPException(status_code=503, detail="Zammad module not available")
|
||||
|
||||
user_id = api_key_context["user_id"]
|
||||
|
||||
request_data = {
|
||||
"action": "get_status"
|
||||
}
|
||||
|
||||
context = {
|
||||
"user_id": user_id,
|
||||
"api_key_id": api_key_context["api_key_id"],
|
||||
"user_permissions": ["modules:*"] # API keys get full module access
|
||||
}
|
||||
|
||||
result = await zammad_module.execute_with_interceptors(request_data, context)
|
||||
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Error getting status: {str(e)}")
|
||||
Reference in New Issue
Block a user