SMS API投递报告(DLR)数据未在URL展示及存储问题求助
无法接收SMS API投递报告(DLR)数据的排查问题
我正在排查无法接收SMS API投递报告(DLR)数据的问题。我编写了代码用于将DLR数据存储至数据库,并创建了视图供用户查看错误信息,但遇到以下问题:
- 错误仅在日志中显示,DLR URL无数据返回
- 访问命名路由
sms.delivery.store对应的页面时显示空白,数据既未存入数据库也未在视图中展示
以下是相关代码:
DeliverReport 控制器
<?php namespace App\Http\Controllers; use App\DeliveryReport; use Illuminate\Http\Request; class DeliveryReportController extends Controller { public function index() { $delivery_reports = DeliveryReport::all(); return view('reports.index', compact('delivery_reports')); } public function store(Request $request){ $data = $request->all(); try { $report = []; if(!empty($data['custom'])) { $report['contact_id'] = $data['contact_id'] ?? ""; $report['msg'] = $data['msg'] ?? ""; $report['contact_no'] = $data['contact_no'] ?? ""; } $report['message_id'] = $data['msgId']; $report['status'] = $data['event']; $report['message'] = $data['errorMessage'] ?? ""; $report['error_code'] = $data['errorCode'] ?? ""; DeliveryReport::create($report); } catch (\Exception $e) { info('something went wrong in webhook'); info($data); info($e->getMessage()); } } }
CommonTrait 代码
<?php namespace App\Http\Traits; use App\SmsHistory; use SMSGate\Client; use SMSGate\SMSRequest; use Carbon\Carbon; use DB; trait CommonServices { public function sms_gate_request($number, $msg, $contact_id){ $gate = new Client(env('SMS_GATE_SUBMIT_URL')); $sms = new SMSRequest; $sms->setType(Client::TYPE_TEXT) ->setAuthUsername(env('SMS_GATE_USERNAME')) ->setAuthPassword(env('SMS_GATE_PASSWORD')) ->setSender(env('SMS_GATE_SENDER')) ->setReceiver($number) ->setText($msg) ->setCustom(['contact_id' => $contact_id, 'msg' => $msg, 'contact_number' => $number]) ->setDlrUrl(route('sms.delivery.store')) ->setDlrMask(Client::DLR_MASK_STANDARD); try { $gate->send($sms); SmsHistory::create([ 'phone_number' => $number, 'message' => $msg, 'contact_id' => $contact_id ]); } catch (\Exception $exc) { info("Error sending SMS with code: " . $exc->getCode() . " and message: " . $exc->getMessage()); return false; } return true; } public function checkMessageCooldown($phone_number, $message) { $days = env('DUPLICATE_SMS_COOLDOWN_DAYS'); $last_sent = Carbon::now()->subDays($days)->toDateTimeString(); $sent_before = DB::table('sms_histories') ->where('phone_number', $phone_number) ->where('message', $message) ->where('created_at', '>', $last_sent) ->exists(); return $sent_before; } }
视图代码
@extends('layouts.app') @section('content') <head> <meta name="_token" content="{{ csrf_token() }}"> <title>Kontaktliste</title> <link rel="stylesheet" href="//cdn.datatables.net/1.10.25/css/jquery.dataTables.min.css"> <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js" ></script> </head> <body> <div class="container"> <div class="row"> <div class="panel panel-default"> <div class="panel-heading"> <div class="row"> <div class="col-md-6"> <h3>Delivery Reports</h3> </div> </div> </div> <div class="panel-body"> <table id="reports-table" class="table table-bordered table-hover"> <thead> <tr> <th>Message ID</th> <th>Contact</th> <th>Message</th> <th>Status</th> <th>Reason (if any error)</th> </tr> </thead> <tbody> @foreach($delivery_reports as $report) <tr> <td>{{ $report->message_id }}</td> <td>{{ $report->contact_id }}</td> <td>{{ $report->message }}</td> <td>{{ $report->status }}</td> <td>{{ $report->error_message }}</td> </tr> @endforeach </tbody> </table> </div> </div> </div> </div> <script src="//cdn.datatables.net/1.10.24/js/jquery.dataTables.min.js" defer></script> <script type="text/javascript"> $(function () { $('#reports-table').DataTable(); }); </script> <script type="text/javascript"> $.ajaxSetup({ headers: { 'csrftoken' : '{{ csrf_token() }}' } }); </script> </body> @endsection
路由配置
Route::get('/delivery_reports/store', 'DeliveryReportController@store')->name('sms.delivery.store');
问题排查与修复建议
- 修正路由请求方法:SMS API的DLR推送通常使用
POST请求,当前配置的GET路由无法正确接收推送数据。修改路由为:
同时,在Route::post('/delivery_reports/store', 'DeliveryReportController@store')->name('sms.delivery.store');app/Http/Middleware/VerifyCsrfToken.php的$except数组中添加该路由,关闭CSRF验证:protected $except = [ '/delivery_reports/store', ]; - 添加响应返回:当前
store方法无任何响应返回,第三方API可能因接收不到确认响应而停止推送或重复请求。在方法末尾添加:return response()->json(['status' => 'success'], 200); - 修正字段名不匹配:Trait中
setCustom传入的是contact_number,但控制器中使用contact_no接收,导致该字段数据为空。修改控制器对应代码:$report['contact_no'] = $data['contact_number'] ?? ""; - 修正视图字段错误:视图中使用
$report->error_message,但控制器存储的是message字段,修改视图对应代码:<td>{{ $report->message }}</td> - 配置模型批量赋值:确保
DeliveryReport模型的$fillable属性包含所有需要存入的字段:protected $fillable = ['contact_id', 'msg', 'contact_no', 'message_id', 'status', 'message', 'error_code'];
内容的提问来源于stack exchange,提问作者Lordp
相关产品推荐
相关产品推荐

