feat: Integrate OpenAI API for email task parsing and update configuration
This commit is contained in:
92
.vscode/ftp-kr.sync.cache.json
vendored
92
.vscode/ftp-kr.sync.cache.json
vendored
@@ -3,34 +3,42 @@
|
||||
"public_html": {
|
||||
"ajax.php": {
|
||||
"type": "-",
|
||||
"size": 1208,
|
||||
"size": 1340,
|
||||
"lmtime": 0,
|
||||
"modified": false
|
||||
"modified": true
|
||||
},
|
||||
"api.php": {
|
||||
"type": "-",
|
||||
"size": 2446,
|
||||
"size": 3758,
|
||||
"lmtime": 0,
|
||||
"modified": false
|
||||
"modified": true
|
||||
},
|
||||
"autoload": {},
|
||||
"ceidg.php": {
|
||||
"type": "-",
|
||||
"size": 3862,
|
||||
"size": 3950,
|
||||
"lmtime": 0,
|
||||
"modified": false
|
||||
"modified": true
|
||||
},
|
||||
".claude": {
|
||||
"settings.local.json": {
|
||||
"type": "-",
|
||||
"size": 72,
|
||||
"lmtime": 1770583517578,
|
||||
"modified": false
|
||||
}
|
||||
},
|
||||
"config.php": {
|
||||
"type": "-",
|
||||
"size": 355,
|
||||
"lmtime": 0,
|
||||
"size": 729,
|
||||
"lmtime": 1770583610342,
|
||||
"modified": false
|
||||
},
|
||||
"cron.php": {
|
||||
"type": "-",
|
||||
"size": 1777,
|
||||
"size": 2093,
|
||||
"lmtime": 0,
|
||||
"modified": false
|
||||
"modified": true
|
||||
},
|
||||
".htaccess": {
|
||||
"type": "-",
|
||||
@@ -40,12 +48,18 @@
|
||||
},
|
||||
"index.php": {
|
||||
"type": "-",
|
||||
"size": 2372,
|
||||
"size": 2464,
|
||||
"lmtime": 0,
|
||||
"modified": false
|
||||
"modified": true
|
||||
},
|
||||
"layout": {},
|
||||
"libraries": {},
|
||||
"REFACTORING_PLAN.md": {
|
||||
"type": "-",
|
||||
"size": 3576,
|
||||
"lmtime": 0,
|
||||
"modified": false
|
||||
},
|
||||
"robots.txt": {
|
||||
"type": "-",
|
||||
"size": 25,
|
||||
@@ -53,7 +67,59 @@
|
||||
"modified": false
|
||||
},
|
||||
"temp": {},
|
||||
"templates": {},
|
||||
"templates": {
|
||||
"tasks": {
|
||||
"filtr_save_form.php": {
|
||||
"type": "-",
|
||||
"size": 775,
|
||||
"lmtime": 0,
|
||||
"modified": false
|
||||
},
|
||||
"main_view_by_ajax.php": {
|
||||
"type": "-",
|
||||
"size": 284,
|
||||
"lmtime": 0,
|
||||
"modified": false
|
||||
},
|
||||
"main_view.php": {
|
||||
"type": "-",
|
||||
"size": 42341,
|
||||
"lmtime": 1770583657535,
|
||||
"modified": false
|
||||
},
|
||||
"task_edit.php": {
|
||||
"type": "-",
|
||||
"size": 10202,
|
||||
"lmtime": 0,
|
||||
"modified": false
|
||||
},
|
||||
"task_popup.php": {
|
||||
"type": "-",
|
||||
"size": 11071,
|
||||
"lmtime": 0,
|
||||
"modified": false
|
||||
},
|
||||
"task_single.php": {
|
||||
"type": "-",
|
||||
"size": 2893,
|
||||
"lmtime": 0,
|
||||
"modified": false
|
||||
},
|
||||
"work-time.php": {
|
||||
"type": "-",
|
||||
"size": 12396,
|
||||
"lmtime": 0,
|
||||
"modified": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": {},
|
||||
"tmp_debug_mail_import.php": {
|
||||
"type": "-",
|
||||
"size": 1238,
|
||||
"lmtime": 0,
|
||||
"modified": false
|
||||
},
|
||||
"upload": {}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -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
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,3 +18,8 @@ $imap_tasks['password'] = 'ProjectPro2025!';
|
||||
|
||||
// Auto-start timer when opening task popup (true/false)
|
||||
$settings['tasks_auto_start_timer'] = false;
|
||||
|
||||
// OpenAI ChatGPT API configuration for email task parsing
|
||||
$settings['openai_api_key'] = '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'; // Wklej tutaj swój klucz API OpenAI
|
||||
$settings['openai_parse_emails'] = true; // true = użyj AI do parsowania emaili, false = normalne parsowanie
|
||||
$settings['openai_model'] = 'gpt-3.5-turbo'; // Model: gpt-3.5-turbo (najtańszy), gpt-4o-mini, gpt-4o, itp.
|
||||
|
||||
Reference in New Issue
Block a user