Viewing file: InboundController.php (19.84 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php
namespace App\Http\Controllers;
use App\Events\SendMail; use App\Models\Contact; use App\Models\Coverage; use App\Models\Customer; use App\Models\CustomerNumber; use App\Models\Exception; use App\Models\Expense; use App\Models\Keyword; use App\Models\KeywordContact; use App\Models\Label; use App\Models\Message; use App\Models\MessageLog; use App\Models\SmsQueue; use App\SmsProvider\SendSMS; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; use Plivo\RestClient; use Plivo\XML\Response; use SignalWire\LaML\MessageResponse as LaML; use SignalWire\Rest\Client; use Textlocal; use Twilio\TwiML\MessagingResponse; use Vonage\Client\Credentials\Basic;
class InboundController extends Controller { public function save_message_log($data, $user) {
return $user->message_logs()->create($data);
}
public function process($type, Request $request) { try { $json = []; $requestData = []; $sms_type=null; if ($type == 'nexmo') { $inbound = \Vonage\SMS\Webhook\Factory::createFromGlobals(); $requestData['vonage_message_id'] = $MessageSid = $inbound->getMessageId(); $requestData['from'] = $From = $inbound->getFrom(); $requestData['to'] = $To = $inbound->getTo(); $requestData['body'] = $Body = $inbound->getText();
if(isset($inbound->type) && $inbound->type=='voice'){ $sms_type='voicecall'; }else if(isset($inbound->type) && $inbound->type=='whatsapp'){ $sms_type='whatsapp'; }else if(isset($inbound->type) && $inbound->type=='mms'){ $sms_type='mms'; }else{ $sms_type='sms'; } if(isset($json['data']['call']['call_control_id'])){ $sms_type='voicecall'; }else if(isset($json['data']['record_type']) && $json['data']['record_type']=='whatsapp'){ $sms_type='whatsapp'; }else if(isset($json['data']['record_type']) && $json['data']['record_type']=='mms'){ $sms_type='mms'; }else{ $sms_type='sms'; } } else if ($type == 'telnyx') { $From = $json["data"]["payload"]["from"]["phone_number"]; $To = $json["data"]["payload"]["to"][0]["phone_number"]; $Body = $json["data"]["payload"]["text"]; $event_type = $json['data']['event_type']; if(isset($json['data']['call']['call_control_id'])){ $sms_type='voicecall'; }else if(isset($json['data']['record_type']) && $json['data']['record_type']=='whatsapp'){ $sms_type='whatsapp'; }else if(isset($json['data']['record_type']) && $json['data']['record_type']=='mms'){ $sms_type='mms'; }else{ $sms_type='sms'; }
if (isset($event_type) && $event_type != "message.received") { exit(); } }else if ($type == 'thinq') { $Body = $request->message; $From = "+1".str_replace('+1','',$request->from); $To = "+1".str_replace('+1','',$request->to); if($request->Type=='WHATSAPP'){ $sms_type='whatsapp'; }else if($request->Type=='VOICECALL'){ $sms_type='voicecall'; }else if($request->Type=='MMS '){ $sms_type='mms'; }else{ $sms_type='sms'; } } else if($type=='twilio'){ $requestData['from'] = $From = "+".str_replace('+','',$request["From"]); $requestData['to'] = $To = "+".str_replace('+','',$request["To"]); $requestData['body'] = $Body = $request["Body"]; if(isset($request["NumMedia"])){ $sms_type='mms'; }else if(isset($request['WaId'])){ $sms_type='whatsapp'; }else if(isset($request['CallSid'])){ $sms_type='voicecall'; }else{ $sms_type='sms'; } }else { $requestData['from'] = $From = "+".str_replace('+','',$request["From"]); $requestData['to'] = $To = "+".str_replace('+','',$request["To"]); $requestData['body'] = $Body = $request["Text"]; } if ($type == 'signalwire') { if (!$request->has('MessageSid')) { return "error"; } $messageObj = json_encode($request->except(['From', 'To', 'Body'])); } else if ($type == 'twilio') { $messageObj = json_encode($request->only(['MessageSid', 'SmsSid', 'AccountSid'])); } else if ($type == 'nexmo') { $messageObj = json_encode(['message_id' => $MessageSid]); } else { $messageObj = json_encode([]); }
$this->inboundMessage($type, $From, $To, $Body, $messageObj, $json, $requestData, $sms_type);
} catch (\Exception $ex) { Log::error($ex->getMessage()); }
}
function sendForwardMessage($type, $from, $to, $body, $newMessage) { try { $sms_queue= SmsQueue::create([ 'to'=>$to, 'from'=>$from, 'body'=>$body, 'message_id'=>$newMessage->id, 'customer_id'=>$newMessage->customer_id, 'type'=>$type, ],['status'=>'succeed']);
$sendSMS = new SendSMS(); $sendSMS->setMessage($sms_queue) ->setType('sent') ->process();
} catch (\Exception $ex) { Log::error("forward message error"); } }
public function gatewayStatus(Request $request) {
$sms_gateway_data = [ 'message_sent_date' => $request->sent_date, 'part_number' => $request->part_number, 'message_cost' => $request->message_cost, 'message_status' => $request->message_status, 'dlr_date' => $request->dlr_date, ]; try { if ($request->message_id && $request->status) { $queue = SmsQueue::where('sms_gateway_message_id', $request->message_id)->first(); $queue->sms_gateway_status = $request->status; $queue->sms_gateway_value = json_encode($sms_gateway_data); $queue->save(); } } catch (\Exception $ex) { Log::error($ex->getMessage()); } return response()->json([], 200);
}
function trigger_webhook($customer_number, $webhookData) { if (isset($customer_number) && isset($customer_number->webhook_url) && isset($customer_number->webhook_method) && $customer_number->webhook_method == 'post') { $client = new \GuzzleHttp\Client(['verify' => false]); $client->post($customer_number->webhook_url, [ 'form_params' => $webhookData ]);
} else if (isset($customer_number) && isset($customer_number->webhook_url) && isset($customer_number->webhook_method) && $customer_number->webhook_method == 'get') { $client = new \GuzzleHttp\Client(['verify' => false]); $client->get($customer_number->webhook_url, [ 'query' => $webhookData ]); } }
public function webhookDeliver(Request $request) {
try { $json = json_decode(file_get_contents("php://input"), true);
if (isset($json["data"]) && isset($json["data"]["id"])) { $responseCode = isset($json["data"]["errors"]) && isset($json["data"]["errors"][0]) && isset($json["data"]["errors"][0]["code"]) ? $json["data"]["errors"][0]["code"] : null; $messageQueue = SmsQueue::where('response_id', $json["data"]["id"])->firstOrFail(); $messageLog = MessageLog::where('response_id', $json["data"]["id"])->firstOrFail(); if ($responseCode) { $messageQueue->response_code = $responseCode; $messageLog->update(['response_code' => $responseCode]); } else { $messageQueue->delivered_at = now(); } $messageQueue->save();
if (isset($json["data"]["errors"])) { $messageLog->update(['status' => 'failed']); $messageQueue->update(['status' => 'failed']); } } return response()->json(['status' => 'success']); } catch (\Exception $ex) { Log::info($ex->getMessage()); return response()->json(['status' => 'failed']); } }
public function checkKeyword($from, $body, $customer_number,$contact) { try { $keyword_contact = null; $keyword = null;
if ($customer_number) { $keyword = Keyword::where(DB::raw('lower(word)'), 'like', '%' . strtolower($body) . '%')->where('customer_number_id', $customer_number->number_id)->first(); } if ($keyword && $contact && $customer_number) { $keyword_contact = KeywordContact::where('keyword_id', $keyword->id)->where('contact_id', $contact->id)->where('customer_id', $customer_number->customer_id)->first(); }
if ($keyword && isset($keyword->type) && $keyword->type == 'opt_out') { $keyword_contact = KeywordContact::where('contact_id', $contact->id)->where('customer_id', $customer_number->customer_id)->first(); if ($keyword_contact) { $keyword_contact->delete(); $contact->delete(); } exit; } else if ($keyword && isset($keyword->type) && $keyword->type == 'opt_in') { $keywordContact = new KeywordContact(); $keywordContact->customer_id = $keyword->customer_id; $keywordContact->keyword_id = $keyword->id; $keywordContact->contact_id = $contact->id; $keywordContact->save(); exit(); } if ($keyword_contact) { Log::info($contact->number . " and " . $keyword->word . " already subscribe"); exit; } return; } catch (\Exception $exception) { Log::error($exception->getMessage()); return; } }
private function checkIfBlocked($contact):bool{ return Exception::where('contact_id',$contact->id)->where('type','block')->count()>0; }
function inboundMessage($type, $From, $To, $Body, $messageObj, $json, $requestData = null, $sms_type) {
$customer_number = CustomerNumber::where('number', $To) ->orWhere('number', str_replace('+', '', $To)) ->orWhere('number', '+' . str_replace('+', '', $To)) ->first(); if (!$customer_number) { Log::info("not found in customer number"); $resp = new Response(); echo $resp->toXML(); exit(); }
$customer=Customer::where('id', $customer_number->customer_id)->firstOrFail(); $wallet = $customer->wallet()->first();
//checking if contact exist or not if not create one $contact = Contact::where('number', $From) ->orWhere('number', str_replace('+', '', $From)) ->orWhere('number', '+' . str_replace('+', '', $From)) ->first(); $label = Label::where('customer_id', $customer_number->customer_id)->where('title', 'new')->first(); if (!$label) { $label = new Label(); $label->title = 'new'; $label->status = 'active'; $label->customer_id = $customer_number->customer_id; $label->color = 'red'; $label->save(); } if (!$contact) { $contact = new Contact(); $contact->customer_id = $customer_number->customer_id; $contact->number = $From; $contact->label_id = $label->id; $contact->save(); } if($this->checkIfBlocked($contact)){ exit(); } $this->checkKeyword($From, $Body, $customer_number,$contact);
$customer = $customer_number->customer; $message = new Message(); $message->customer_id = $customer->id; $message->body = $Body; $message->numbers = json_encode(['from' => $From, 'to' => [$To]]); $message->type = 'inbox'; $message->message_obj = $messageObj; $message->save();
//TODO::Credit minus for inbox sms $current_plan = auth('customer')->user()->plan; if (!$current_plan){ exit(); } $coverages=Coverage::whereIn('id', json_decode($current_plan->coverage_ids))->get(); $coverage_rate = []; if ($coverages) { foreach ($coverages as $coverage) { if (isset($sms_type) && $sms_type == 'sms') { $coverage_rate[$coverage->country_code] = $coverage->plain_sms; } else if (isset($sms_type) &&$sms_type== 'mms') { $coverage_rate[$coverage->country_code] = $coverage->send_mms; } else if (isset($sms_type) &&$sms_type == 'whatsapp') { $coverage_rate[$coverage->country_code] = $coverage->send_voice_sms; } else if (isset($sms_type) &&$sms_type == 'voicecall') { $coverage_rate[$coverage->country_code] = $coverage->send_whatsapp_sms; } } } $totalSmsAmount=$coverage_rate[str_replace('+','',$contact->contact->contact_dial_code)];
$totalCount=1; $requestCharacters=$Body; $characters=mb_strlen($requestCharacters, "UTF-8"); if (strlen($requestCharacters) != strlen(utf8_decode($requestCharacters))) { if($characters && $characters > 70){ $grandTotal=ceil($characters / 70); if($grandTotal > 1) $totalCount= $grandTotal; } }else { if($characters && $characters > 160){ $grandTotal=ceil($characters / 160); if($grandTotal > 1) $totalCount= $grandTotal; } } $totalSmsCredit= ($totalSmsAmount * $totalCount);
if($totalSmsCredit > $wallet->credit){ Log::info('Low Credit'); exit(); }
$wallet->credit = $wallet->credit - $totalSmsCredit; $wallet->save();
if(!isset($sms_type) || !$sms_type){ $sms_type='sms'; }
$messageLog = $this->save_message_log(['to' => $To, 'from' => $From, 'body' => $Body, 'message_id' => $message->id, 'type' => 'inbox','from_type'=>$sms_type], $customer);
if (isset($json["data"]["cost"])) { $expense = new Expense(); $expense->type = 'receive'; $expense->cost = $json["data"]["cost"]['amount']; $expense->message_log_id = $messageLog->id; $expense->customer_id = $message->customer_id; $expense->save(); }
if ($customer_number->forward_to) { $this->sendForwardMessage($type, $customer_number->number, $customer_number->forward_to_dial_code . $customer_number->forward_to, $Body, $message); } if ($customer_number->webhook_url) { $requestData['webhook_url']=url()->current(); $this->trigger_webhook($customer_number, $requestData); }
if (isset($customer) && isset($customer->email)) { $notification = $customer->settings()->where('name', 'email_notification')->first(); if (isset($notification->value) && $notification->value == 'true' && $Body) { SendMail::dispatch($customer->email, 'New Message', $Body); } }
$this->generateResponse($type); // NB: If you are adding new sms gateway make sure you return response based on type
}
public function plivoWebhook($message_id, Request $request) { $messageId = $message_id; $to = $request->To; $from = $request->From; $MessageUUID = $request->MessageUUID; $status = $request->Status; $errorCode = $request->ErrorCode; $messageStatus = 'succeed'; $smsQueueStatus = 'running';
if (!$messageId || !$to || !$from || !$MessageUUID || !$status) { exit(); }
if ($status == 'queued') { exit(); }
try { if ($status == 'failed' || $status == 'undelivered' || $status == 'rejected') { $messageStatus = 'failed'; $smsQueueStatus = 'failed'; } else if ($status == 'sent' || $status == 'delivered') { $messageStatus = 'succeed'; $smsQueueStatus = 'running'; } // For Message Log MessageLog::where('message_id', $messageId)->where('response_id', $MessageUUID)->where(function ($q) use ($to) { $q->where('to', $to)->orWhere('to', '+' . str_replace('+', '', $to))->orWhere('to', str_replace('+', '', $to)); })->where(function ($q) use ($from) { $q->where('from', $from)->orWhere('from', '+' . str_replace('+', '', $from))->orWhere('from', str_replace('+', '', $from)); })->update(['status' => $messageStatus, 'response_code' => $errorCode]);
// For SMS Queue SmsQueue::where('message_id', $messageId)->where('response_id', $MessageUUID)->where(function ($q) use ($to) { $q->where('to', $to)->orWhere('to', '+' . str_replace('+', '', $to))->orWhere('to', str_replace('+', '', $to)); })->where(function ($q) use ($from) { $q->where('from', $from)->orWhere('from', '+' . str_replace('+', '', $from))->orWhere('from', str_replace('+', '', $from)); })->update(['status' => $smsQueueStatus, 'response_code' => $errorCode]);
if ($status == 'delivered') { $messageLog = MessageLog::where('message_id', $messageId)->where('response_id', $MessageUUID)->where(function ($q) use ($to) { $q->where('to', $to)->orWhere('to', '+' . str_replace('+', '', $to))->orWhere('to', str_replace('+', '', $to)); })->where(function ($q) use ($from) { $q->where('from', $from)->orWhere('from', '+' . str_replace('+', '', $from))->orWhere('from', str_replace('+', '', $from)); })->first(); if(!$messageLog){ exit(); } $totalAmount = $request->TotalAmount; $expense = new Expense(); $expense->type = 'sent'; $expense->cost = $totalAmount; $expense->message_log_id = $messageLog->id; $expense->customer_id = $messageLog->customer_id; $expense->save(); } return response()->json(['data' => 'success'], 200); } catch (\Exception $ex) { Log::error($ex); return response()->json(['message' => $ex->getMessage()], 404); } }
public function generateResponse($type) { if ($type == 'signalwire') { $resp = new MessagingResponse(); echo $resp; } else if ($type == 'twilio') { $resp = new MessagingResponse(); echo $resp; } else if ($type == 'telnyx') { $resp = new MessagingResponse(); echo $resp; } else if ($type == 'plivo') { $resp = new Response(); echo $resp->toXML(); } } }
|