Skip to content

Commit

Permalink
feat: add PDF data extraction and AI lead creation functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
amit-webkul committed Jan 28, 2025
1 parent 054d0b6 commit 27ef6e2
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 11 deletions.
76 changes: 72 additions & 4 deletions packages/Webkul/Admin/src/Helpers/Lead.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,83 @@
namespace Webkul\Admin\Helpers;

use Smalot\PdfParser\Parser;
use Exception;

class Lead
{
/**
* Extract data from a PDF and process it via LLM API.
*/
public static function extractDataFromPdf($pdfPath)
{
$parser = new Parser;
$pdf = $parser->parseFile($pdfPath);
$text = $pdf->getText();
try {
$parser = new Parser();
$pdf = $parser->parseFile($pdfPath);
$text = trim($pdf->getText());

return $text;
if (empty($text)) {
throw new Exception("PDF content is empty or could not be extracted.");
}

return self::sendLLMRequest($text);
} catch (Exception $e) {
return ["error" => $e->getMessage()];
}
}

/**
* Send a request to the LLM API.
*/
private static function sendLLMRequest($prompt)
{
$url = "https://api.openai.com/v1/chat/completions";

$model = core()->getConfigData('general.magic_ai.settings.model');
$apiKey = core()->getConfigData('general.magic_ai.settings.api_key');

if (empty($apiKey) || empty($model)) {
return ["error" => "Missing API key or model configuration."];
}

$data = [
"model" => $model,
"messages" => [
["role" => "system", "content" => "You are an AI assistant."],
["role" => "user", "content" => $prompt]
],
"max_tokens" => 200
];

try {
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Content-Type: application/json",
"Authorization: Bearer " . $apiKey
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

if (curl_errno($ch)) {
throw new Exception("cURL Error: " . curl_error($ch));
}

curl_close($ch);

$decodedResponse = json_decode($response, true);

if ($httpCode !== 200 || isset($decodedResponse['error'])) {
throw new Exception("LLM API Error: " . ($decodedResponse['error']['message'] ?? 'Unknown error'));
}

return $decodedResponse;
} catch (Exception $e) {
return ["error" => $e->getMessage()];
}
}
}
48 changes: 41 additions & 7 deletions packages/Webkul/Admin/src/Http/Controllers/Lead/LeadController.php
Original file line number Diff line number Diff line change
Expand Up @@ -627,19 +627,53 @@ private function getKanbanColumns(): array
];
}

public function createByAI()
public function createByAI(LeadForm $request)
{
if ($pdfFile = request()->file('file')) {
if ($pdfFile = $request->file('file')) {
$pdfPath = $pdfFile->getPathName();

$extractedData = Lead::extractDataFromPdf($pdfPath);

dd($extractedData);
if (isset($extractedData['error'])) {
return response()->json([
'status' => 'error',
'message' => $extractedData['error'],
], 400);
}

return response()->json([
'status' => 'success',
'data' => $extractedData,
]);
$leadData = $this->mapAIDataToLead($extractedData);

$validatedData = app(LeadForm::class)->validated();

$finalData = array_merge($validatedData, $leadData);

dd($finalData);

return $this->store(new LeadForm($finalData));
}

return response()->json([
'status' => 'error',
'message' => 'No file uploaded.',
], 400);
}

private function mapAIDataToLead($aiData)
{
return [
'status' => 1,
'title' => $aiData['lead_title'] ?? 'Untitled Lead',
'person' => [
'name' => $aiData['contact_name'] ?? 'Unknown',
'email' => $aiData['contact_email'] ?? null,
'phone' => $aiData['contact_phone'] ?? null,
'organization_id' => $aiData['organization_id'] ?? null,
],
'lead_pipeline_stage_id' => $aiData['pipeline_stage_id'] ?? null,
'value' => $aiData['lead_value'] ?? 0,
'source' => $aiData['source'] ?? 'AI Extracted',
];
}


}

0 comments on commit 27ef6e2

Please sign in to comment.