feat: Integrate OpenAI API for email task parsing and update configuration

This commit is contained in:
2026-02-08 22:48:57 +01:00
parent 0c5a133aa7
commit 63268e35dc
3 changed files with 204 additions and 15 deletions

View File

@@ -88,8 +88,34 @@ class MailToTaskImporter
try
{
$content = $this -> extractMessageContent( $imap, $message_no );
$task_name = trim( $subject ) !== '' ? trim( $subject ) : '(bez tematu)';
$task_text = $this -> prepareImportedTaskText( $content['text'] );
// Sprawdź czy użyć AI do parsowania
global $settings;
$use_ai = isset( $settings['openai_parse_emails'] ) && $settings['openai_parse_emails'] === true;
$api_key = isset( $settings['openai_api_key'] ) ? trim( (string)$settings['openai_api_key'] ) : '';
if ( $use_ai && $api_key !== '' )
{
$model = isset( $settings['openai_model'] ) ? trim( (string)$settings['openai_model'] ) : 'gpt-3.5-turbo';
$ai_result = $this -> parseWithAI( $api_key, $model, $subject, $content['text'] );
if ( $ai_result !== null )
{
$task_name = $ai_result['task_name'];
$task_text = $ai_result['task_text'];
}
else
{
// Fallback do normalnego parsowania jeśli AI nie zadziała
$task_name = trim( $subject ) !== '' ? trim( $subject ) : '(bez tematu)';
$task_text = $this -> prepareImportedTaskText( $content['text'] );
}
}
else
{
// Normalne parsowanie
$task_name = trim( $subject ) !== '' ? trim( $subject ) : '(bez tematu)';
$task_text = $this -> prepareImportedTaskText( $content['text'] );
}
$client_id = $this -> resolveClientIdBySenderDomain( $sender );
$task_id = \factory\Tasks::task_save(
@@ -648,4 +674,96 @@ class MailToTaskImporter
$value = trim( $value, '<>' );
return strtolower( $value );
}
private function parseWithAI( $api_key, $model, $subject, $raw_content )
{
$subject = trim( (string)$subject );
$raw_content = trim( (string)$raw_content );
$model = trim( (string)$model );
if ( $model === '' )
$model = 'gpt-3.5-turbo';
// Przygotuj treść do analizy (usuń HTML jesli jest)
if ( preg_match( '/<\s*[a-z][^>]*>/i', $raw_content ) )
{
$raw_content = $this -> htmlToText( $raw_content );
$raw_content = $this -> cleanBodyText( $raw_content );
}
$prompt = "Jesteś asystentem do przetwarzania emaili na zadania w systemie CRM. " .
"Na podstawie poniższego tematu i treści emaila, wygeneruj:\n" .
"1. Zwięzły, konkretny temat zadania (max 100 znaków)\n" .
"2. Czytelny opis zadania zawierający najważniejsze informacje\n\n" .
"Temat emaila: " . $subject . "\n\n" .
"Treść emaila:\n" . mb_substr( $raw_content, 0, 2000 ) . "\n\n" .
"Odpowiedz TYLKO w formacie JSON bez żadnych dodatkowych wyjaśnień:\n" .
'{"task_name": "temat zadania", "task_text": "opis zadania"}';
$payload = [
'model' => $model,
'messages' => [
[
'role' => 'system',
'content' => 'Jesteś asystentem do przetwarzania emaili. Odpowiadasz TYLKO w formacie JSON.'
],
[
'role' => 'user',
'content' => $prompt
]
],
'temperature' => 0.3,
'max_tokens' => 500
];
$ch = curl_init( 'https://api.openai.com/v1/chat/completions' );
curl_setopt_array( $ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode( $payload ),
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Authorization: Bearer ' . $api_key
],
CURLOPT_TIMEOUT => 30
] );
$response = curl_exec( $ch );
$http_code = curl_getinfo( $ch, CURLINFO_HTTP_CODE );
curl_close( $ch );
if ( $http_code !== 200 || !$response )
return null;
$data = json_decode( $response, true );
if ( !isset( $data['choices'][0]['message']['content'] ) )
return null;
$content = trim( $data['choices'][0]['message']['content'] );
// Usuń markdown code block jeśli jest
$content = preg_replace( '/```json\s*|\s*```/', '', $content );
$content = trim( $content );
$parsed = json_decode( $content, true );
if ( !is_array( $parsed ) || !isset( $parsed['task_name'] ) || !isset( $parsed['task_text'] ) )
return null;
$task_name = trim( (string)$parsed['task_name'] );
$task_text = trim( (string)$parsed['task_text'] );
if ( $task_name === '' )
$task_name = '(bez tematu)';
if ( $task_text === '' )
$task_text = '(brak treści)';
// Formatuj treść zadania z nl2br
$task_text = nl2br( $task_text );
return [
'task_name' => $task_name,
'task_text' => $task_text
];
}
}