shopid.ir ->open source online shop solutions
ارسال نوتیفیکیشن به مرورگر با لاراول
نوتیفیکیشن یک جز جدا نشدنی از فروشگاه های اینترنتیه !
خیلی خوب میشه وقتی سفارش مشتری آماده به ارسال میشه یه نوتیفیکیشن کوچیک هم براش ارسال بشه و بگه سفارش شما ارسال شد !
اینجوری هم مشتری راضی میشه هم اینکه کلی وقت و انرژی از اپراتور و مشتری هدر نمیره
مشاهده ی این آموزش توی یوتوب : 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: "https://www.shopid.ir/shopid.png",
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 [▼
"publicKey" => "BJjPvcv9QQu3SVxvjP_WpQNeuyhWKpGozAXkab2rl6VTaMv18R4avQy5dKcudeEbCbRNMR_kRkbPxV957fxXbP8"
"privateKey" => "oy468fjwBBSf_3OifCNsyHisxyf4FCgQBgM77Jd8uGs"
]
خب اینو یه جا ذخیره کنید و 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([
"pushdata"=>$request->push
]);
}
public function index()
{
return view("admin",["pushes"=>push::latest()->limit(10)->get()]);
}
public function send(Request $req , push $push)
{
$webPush = new WebPush([
"VAPID" => [
"subject" => "http://localhost",
"publicKey" => 'BJjPvcv9QQu3SVxvjP_WpQNeuyhWKpGozAXkab2rl6VTaMv18R4avQy5dKcudeEbCbRNMR_kRkbPxV957fxXbP8',
"privateKey" => "oy468fjwBBSf_3OifCNsyHisxyf4FCgQBgM77Jd8uGs"
]
]);
$subscription = Subscription::create(json_decode($push->pushdata,true));
$response = $webPush->sendOneNotification($subscription,json_encode(["title"=>"new notif","body"=>$req->text,"url"=>$req->url]));
if ($response->isSuccess()) {
echo "ok"
} else {
$response->getReason();
}
}
دقت کنید که privateKey و publicKey از همونی که قبلا گرفتیم و سیو کردیم باید استفاده کنیم
توی مدلمون (push.php) fillable برای فیلد pushdata تعریف میکنیم
protected $fillable = [
'pushdata'
];
حالا روت هامونو تعریف میکنیم
api.php
Route::post('admin/savepush',"App\Http\Controllers\PushController@store");
web.php
Route::get('/admin', "App\Http\Controllers\PushController@index");
Route::post('/admin/sendpush/{push}', "App\Http\Controllers\PushController@send");
حالا ویوهامونو میسازیم
ویوو اصلی یا هرجایی که میخوایم از کاربر اجازه بگیریم یه همچین چیزی میشه (اینجا همون welcome.blade.php) :
پارامتر applicationServerKey همون کلید عمومی هست که بالاتر گرفتیم و همینجا میذاریمش و مشکلی هم نداره که در سورسمون باشه
اون قسمت XMLHttpRequest هم خیلی ساده نوشتم که مقداری که میگیریم بفرستیم به بکاندمون اگه توی پروژتون جور دیگه ای ارسال میکنید با همون روش ارسال کنید
(فقط باید push به صورت جیسان شده ذخیره بشه)
welcome.blade.php :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<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:"BJjPvcv9QQu3SVxvjP_WpQNeuyhWKpGozAXkab2rl6VTaMv18R4avQy5dKcudeEbCbRNMR_kRkbPxV957fxXbP8"
});
let xhr = new XMLHttpRequest()
xhr.open('POST', '/api/admin/savepush', true)
xhr.setRequestHeader('Content-type', 'application/json; charset=UTF-8')
xhr.send(JSON.stringify({"push":JSON.stringify(push)}));
}
function enableNotif() {
Notification.requestPermission().then(function (permission) {
if (Notification.permission === 'granted') {
subscribe()
}
});
}
<button ="enableNotif();" style="font-size: 5rem">enableNotif</button>
</body>
</html>
یه ویو دیگه هم میسازیم به اسم admin.blade.php که همونجاییه که میخوایم به کاربرامون نوتیفیکیشن ارسال کنیم میتونید به صورت api هم انجام بدید اینجا به ساده ترین حالت داریم اینجام میدیم
admin.blade.php :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
@foreach($pushes as $push)
<form method="post" action="/admin/sendpush/{{$push->id}}" target="_blank">
push {{$push->id}}
<input name="text" type="text" placeholder="text">
<input name="url" type="text" placeholder="https://">
<input type="submit" value="send"/>
{{ csrf_field() }}
</form>
@endforeach
</body>
</html>
خب تموم شد الان فقط باید پروژمونو ران کنیم و هر کاربری بیاد توی سایتمون و enableNotif بزنه یه توکن و اندپوینت براش توی دیتابیس ما ذخیره میشه و اگه ما بریم توی قسمت ادمین (http://127.0.0.1:8000/admin) میتونیم براش نوتیفیکیشن ارسال کنیم !
مقدار text همون متنه و url هم برای وقتیه که کاربر روی نوتیفیکشن کلیک میکنه و وارد همون url میشه
مطلبی دیگر از این انتشارات
نگاهی به سربازی اجباری
مطلبی دیگر از این انتشارات
متد filter در جاوااسکریپت
مطلبی دیگر از این انتشارات
کاربرد دو کلید esc و del در نرم افزار اکسل