ارسال نوتیفیکیشن به مرورگر با لاراول

نوتیفیکیشن یک جز جدا نشدنی از فروشگاه های اینترنتیه !خیلی خوب میشه وقتی سفارش مشتری آماده به ارسال میشه یه نوتیفیکیشن کوچیک هم براش ارسال بشه و بگه سفارش شما ارسال شد !اینجوری هم مشتری راضی میشه هم اینکه کلی وقت و انرژی از اپراتور و مشتری هدر نمیرهمشاهده ی این آموزش توی یوتوب :‌ https://www.youtube.com/watch?v=F5I5mfVZKxIخب حالا چطور باید اینکارو با لاراول انجام بدیم ؟خیلی سادهکلا داستان نوتیفیکیشن توی مرورگر ها چه دسکتاپ چه موبایل با یه تابع انجام میشه !new Notification('salam');همین الان همینو توی کنسول مروگر وارد کنید میبینید که هیچی نمیشه ?چون که به احتمال ۹۹ درصد هنوز اجازه ی ارسال نوتیفیکیشن به مرورگر رو ندادیدبرای اینکه اجازه بدید ، توی آدرس بار کنار اسم سایت روی علامت قفل یا همون ssl کلیک کنید و توی site setting نوتیفیکیشن allow کنید و دوباره همون کد بالا رو بزنید میبینید که شدخب درسته هیچ سایتی اینجوری نوفیکیشن ارسال نمیکنه ، اصلش اینجوریه که نوتیفیکیشن باید وقتی کاربر توی سایتمون نیست ارسال بشه تا دوباره بیاریمش توی سایتمون !مراحل عملکرد پوش نوتیفیکیشن :کاربر وارد سایت میشهاز کاربر درخواست میشه اجازه بده که براش نوتیفیکیشن ارسال بشهاگر کاربر اجازه داد pushManager.subscribe اجرا میشه و یک سری اطلاعات و آدرس اندپوینت مروگر به ما داده میشه مثلا برای کروم همچین چیزیه fcm.googleapis.com/fcm/send یا برای فایرفاکس updates.push.services.mozilla.com و ما باید این مقادیرو به صورت جی‌سان توی دیتابیسمون برای یوزر ذخیره کنیمما از طریق سرورمون به این اندپوینت درخواست میفرستیم و اون درخواستو به کاربر میفرسته !بریم که انجامش بدیمشروعاول از همه یه پروژه با لاراول استارت میزنیمتوی فولدر پابلیک یا هرجایی که میشه یه فایل js درست کرد و بهش دست رسی داریم یه فایل درست میکنیم یعنی اینجوری مثلا https://www.site.com/file.jsاسمشو معمولا میذارن sw.js که همون service worker هست ، هر اسم دیگه ای هم میتونید بذاریدداخل این فایل اینو بنویسید :self.addEventListener('push', (e) => { let data = e.data.json(); const options = { body: data.body, icon: &quothttps://www.shopid.ir/shopid.png&quot, data: { url: data.url } } e.waitUntil(self.registration.showNotification(data.title, options)); }); self.addEventListener('notificationclick', function(e) { e.waitUntil(clients.openWindow(e.notification.data.url)) });درست حدس زدید icon همون آیکونیه که کنار نوتیفیکشنتون قراره بیاد(بقیه داکیومنتاش اینجا هست )شما الان یه سرویس ورکر برای نوتیفیکیشن نوشتید !که وقتی کاربر روش کلیک میکنه میره به آدرسی که ما میخوایم !ولی هنوز یه سری کارای دیگه باید انجام بدیممرحله ای بعدی باید یه پکیج php روی لاراولمون نصب کنیم composer require minishlink/web-pushخب حالا ما نیاز داریم که دوتا کلید بگیریم یکی پابلیک و یکی پرایویتو اینکارو یک بار نیاز داریم بکینمپس هرجا که میتونید از پیکیج minishlink/web-push استفاده کنید اینکارو میتونید بکنیدبهترین جایی که میشه اینکارو کرد web.php هست همونجایی که route هارو تعریف میکنیمپس همونجا این کد بنویسید :use Minishlink\WebPush\VAPID; dd(VAPID::createVapidKeys());یه بار سایتو ران کنید یه همچین چیزی میبینیدarray:2 [▼ &quotpublicKey&quot => &quotBJjPvcv9QQu3SVxvjP_WpQNeuyhWKpGozAXkab2rl6VTaMv18R4avQy5dKcudeEbCbRNMR_kRkbPxV957fxXbP8&quot &quotprivateKey&quot => &quotoy468fjwBBSf_3OifCNsyHisxyf4FCgQBgM77Jd8uGs&quot ]خب اینو یه جا ذخیره کنید و web.php به حالت اولش برگردونید یعنی اون dd(VAPID::createVapidKeys()) پاک کنیدحالا میریم و مدل و مایگریشن و کنترلمونو میسازیمphp artisan make:model push -mcrتوی فیلد های مایگریشن pushes یه فیلد تکست اضافه میکنیم$table->text('pushdata');و بعدش :php artisan migrateحالا میریم توی کنترلرمون (PushController.php) و متد های store و index و send اینجوری میسازییمpublic function store(Request $request) { push::create([ &quotpushdata&quot=>$request->push ]); } public function index() { return view(&quotadmin&quot,[&quotpushes&quot=>push::latest()->limit(10)->get()]); } public function send(Request $req , push $push) { $webPush = new WebPush([ &quotVAPID&quot => [ &quotsubject&quot => &quothttp://localhost&quot, &quotpublicKey&quot => 'BJjPvcv9QQu3SVxvjP_WpQNeuyhWKpGozAXkab2rl6VTaMv18R4avQy5dKcudeEbCbRNMR_kRkbPxV957fxXbP8', &quotprivateKey&quot => &quotoy468fjwBBSf_3OifCNsyHisxyf4FCgQBgM77Jd8uGs&quot ] ]); $subscription = Subscription::create(json_decode($push->pushdata,true)); $response = $webPush->sendOneNotification($subscription,json_encode([&quottitle&quot=>&quotnew notif&quot,&quotbody&quot=>$req->text,&quoturl&quot=>$req->url])); if ($response->isSuccess()) { echo &quotok&quot } else { $response->getReason(); } } دقت کنید که privateKey و publicKey از همونی که قبلا گرفتیم و سیو کردیم باید استفاده کنیمتوی مدلمون (push.php) fillable برای فیلد pushdata تعریف میکنیم protected $fillable = [ 'pushdata' ]; حالا روت هامونو تعریف میکنیم api.php Route::post('admin/savepush',&quotApp\Http\Controllers\PushController@store&quot); web.php Route::get('/admin', &quotApp\Http\Controllers\PushController@index&quot); Route::post('/admin/sendpush/{push}', &quotApp\Http\Controllers\PushController@send&quot); حالا ویوهامونو میسازیمویوو اصلی یا هرجایی که میخوایم از کاربر اجازه بگیریم یه همچین چیزی میشه (اینجا همون welcome.blade.php) :پارامتر applicationServerKey همون کلید عمومی هست که بالاتر گرفتیم و همینجا میذاریمش و مشکلی هم نداره که در سورسمون باشهاون قسمت XMLHttpRequest هم خیلی ساده نوشتم که مقداری که میگیریم بفرستیم به بک‌اندمون اگه توی پروژتون جور دیگه ای ارسال میکنید با همون روش ارسال کنید(فقط باید push به صورت جی‌سان شده ذخیره بشه)welcome.blade.php :<!DOCTYPE html> <html lang=&quoten&quot> <head> <meta charset=&quotUTF-8&quot> <meta name=&quotviewport&quot content=&quotwidth=device-width, initial-scale=1.0&quot> <meta http-equiv=&quotX-UA-Compatible&quot content=&quotie=edge&quot> <title>Document</title> </head> <body> navigator.serviceWorker.register('sw.js'); async function subscribe() { let sw = await navigator.serviceWorker.ready; let push = await sw.pushManager.subscribe({ userVisibleOnly:true, applicationServerKey:&quotBJjPvcv9QQu3SVxvjP_WpQNeuyhWKpGozAXkab2rl6VTaMv18R4avQy5dKcudeEbCbRNMR_kRkbPxV957fxXbP8&quot }); let xhr = new XMLHttpRequest() xhr.open('POST', '/api/admin/savepush', true) xhr.setRequestHeader('Content-type', 'application/json; charset=UTF-8') xhr.send(JSON.stringify({&quotpush&quot:JSON.stringify(push)})); } function enableNotif() { Notification.requestPermission().then(function (permission) { if (Notification.permission === 'granted') { subscribe() } }); } <button =&quotenableNotif();&quot style=&quotfont-size: 5rem&quot>enableNotif</button> </body> </html> یه ویو دیگه هم میسازیم به اسم admin.blade.php که همونجاییه که میخوایم به کاربرامون نوتیفیکیشن ارسال کنیم میتونید به صورت api هم انجام بدید اینجا به ساده ترین حالت داریم اینجام میدیمadmin.blade.php :<!DOCTYPE html> <html lang=&quoten&quot> <head> <meta charset=&quotUTF-8&quot> <meta name=&quotviewport&quot content=&quotwidth=device-width, initial-scale=1.0&quot> <meta http-equiv=&quotX-UA-Compatible&quot content=&quotie=edge&quot> <title>Document</title> </head> <body> @foreach($pushes as $push) <form method=&quotpost&quot action=&quot/admin/sendpush/{{$push->id}}&quot target=&quot_blank&quot> push {{$push->id}} <input name=&quottext&quot type=&quottext&quot placeholder=&quottext&quot> <input name=&quoturl&quot type=&quottext&quot placeholder=&quothttps://&quot> <input type=&quotsubmit&quot value=&quotsend&quot/> {{ csrf_field() }} </form> @endforeach </body> </html> خب تموم شد الان فقط باید پروژمونو ران کنیم و هر کاربری بیاد توی سایتمون و enableNotif بزنه یه توکن و اندپوینت براش توی دیتابیس ما ذخیره میشه و اگه ما بریم توی قسمت ادمین (http://127.0.0.1:8000/admin) میتونیم براش نوتیفیکیشن ارسال کنیم !مقدار text همون متنه و url هم برای وقتیه که کاربر روی نوتیفیکشن کلیک میکنه و وارد همون url میشه