Skip to content

Instantly share code, notes, and snippets.

@codemonkey76
Created February 10, 2024 02:50
Show Gist options
  • Save codemonkey76/7aa85a3da3af8cb2cedd74d51d0ccef1 to your computer and use it in GitHub Desktop.
Save codemonkey76/7aa85a3da3af8cb2cedd74d51d0ccef1 to your computer and use it in GitHub Desktop.
Inbound mail controller
<?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