Created
February 10, 2024 02:50
-
-
Save codemonkey76/7aa85a3da3af8cb2cedd74d51d0ccef1 to your computer and use it in GitHub Desktop.
Inbound mail controller
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php declare(strict_types=1); | |
namespace App\Http\Controllers; | |
use Mail; | |
use Exception; | |
use Spatie\Regex\Regex; | |
use App\Models\Customer; | |
use App\Mail\NewVoicemail; | |
use App\Models\Voicemailbox; | |
use App\Jobs\TranscribeVoicemail; | |
use Illuminate\Support\Facades\Log; | |
use Illuminate\Support\Facades\Storage; | |
use Spatie\Regex\Exceptions\RegexFailed; | |
class InboundMailController extends Controller | |
{ | |
/** | |
* @throws Exception | |
*/ | |
protected function validateAttachment() { | |
if (!request()->hasFile('attachment-1')) { | |
Log::channel('voicemail')->warning('Received voicemail email - no voicemail was found attached'); | |
throw new Exception('No attachment', 406); | |
} | |
Log::channel('voicemail')->info('Received voicemail from Mailgun with audio-file attachment'); | |
} | |
/** | |
* @throws RegexFailed | |
*/ | |
protected function extractData(): array | |
{ | |
$content = request('stripped-text'); | |
$results = Regex::match("/Caller ID: (?<caller>[^\s]*).*Domain: (?<domain>[^\s]*).*Voicemail ID: (?<voicemail>[\d]*)/", $content); | |
$data = [ | |
'caller' => $results->group('caller'), | |
'domain' => $results->group('domain'), | |
'voicemail' => $results->group('voicemail') | |
]; | |
Log::channel('voicemail')->info("Extracted caller ({$data['caller']}) - domain ({$data['domain']}) - voicemail ({$data['voicemail']})"); | |
return $data; | |
} | |
/** | |
* @throws Exception | |
*/ | |
protected function getVoicemailbox(Customer|null $customer, $domain, $voicemailId): Voicemailbox | |
{ | |
if (is_null($customer)) { | |
Log::channel('voicemail')->warning("Received voicemail from mailgun, could not find customer with matching domain: $domain"); | |
throw new Exception("Customer not found with domain $domain", 406); | |
} | |
$voicemailBox = $customer->voicemailboxes()->whereVoicemailId($voicemailId)->first(); | |
if (is_null($voicemailBox)) { | |
Log::channel('voicemail')->warning("No Voicemail Box in system with id: $voicemailId"); | |
throw new \Exception('Voicemail Box not found', 406); | |
} | |
Log::channel('voicemail')->info('Found matching voicemail box in system'); | |
return $voicemailBox; | |
} | |
/** | |
* @throws Exception | |
*/ | |
protected function storeVoicemailFile() | |
{ | |
try { | |
$file = Storage::disk('s3')->put('/voicemail', request()->file('attachment-1')); | |
} catch (Exception $e) { | |
throw new \Exception("Unable to store voicemail audio file on S3: {$e->getMessage()}"); | |
} | |
Log::channel('voicemail')->info("Storing voicemail file ($file) on S3 Bucket"); | |
return $file; | |
} | |
public function store() | |
{ | |
try { | |
$this->validateAttachment(); | |
['domain' => $domain, 'caller' => $caller, 'voicemail' => $voicemailId] = $this->extractData(); | |
$customer = Customer::whereDomain($domain)->first(); | |
$voicemail = $this->getVoicemailbox($customer, $domain, $voicemailId); | |
$file = $this->storeVoicemailFile(); | |
if ($voicemail->notify_sms) { | |
Log::channel('voicemail')->info('notify_sms = true, dispatching Transcribe job'); | |
TranscribeVoicemail::dispatch($voicemail, $customer, $caller, $file); | |
} | |
if ($voicemail->notify_email) { | |
Log::channel('voicemail')->info('notify_email = true, dispatching Mail job'); | |
// Mail::to($voicemail->email)->send(new NewVoicemail($voicemail, $caller, $file)); | |
} | |
return response('OK', 200); | |
} catch (Exception $e) { | |
Log::channel('voicemail')->error("Error processing voicemail: {$e->getMessage()}"); | |
return response('Error', 500); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment