如何使用 Laravel Pusher 从管理员向特定用户按 ID 发送通知。

huangapple go评论41阅读模式
英文:

how to send notification from admin to user by id with Laravel Pusher

问题

在我的 Laravel 应用程序中,我已经成功地实现了 Pusher,但我想要这样做:当用户成功下订单时,默认订单的状态消息是 `pending`。具体情况是,当管理员将状态消息更改为 `processed` 时,已下订单的用户会收到通知,告知他的订单已处理。

但是当前的代码会向所有用户发送通知。

**Controller**

```php
if ($data->status_message == 'processed') {
   event(new OrderEvent('Hi, Your order is processed!'));

   // 其他操作...
}

My Event OrderEvent.php

public function broadcastOn()
{
    return new Channel('notif-channel');
}

/**
 * Broadcast order event.
 * 
 * @return void
 */
public function broadcastAs()
{
    return 'order-event';
}

在 App blade 中

var channel = pusher.subscribe('notif-channel');
channel.bind('order-event', function(data) {

    const obj = JSON.parse(JSON.stringify(data));
    const message = obj.message;
    
    // 其他处理...
}

<details>
<summary>英文:</summary>

I have successfully implemented pusher on my laravel app but I want to make, when the user succeeds in making an order the default status_message for the order is `pending`, the case is when the admin changes the status_message to `processed`, the user who has ordered gets a notification that the order he has made is processed.

this is my code but this code sends notifications to all users.

**Controller**

    if ($data-&gt;status_message == &#39;processed&#39;) {
       event(new OrderEvent(&#39;Hi, Your order is processed!&#39;));

       //...
    }

**My Event OrderEvent.php**

    public function broadcastOn()
    {
        return new Channel(&#39;notif-channel&#39;);
    }

    /**
     * Broadcast order event.
     * 
     * @return void
     */
    public function broadcastAs()
    {
        return &#39;order-event&#39;;
    }

**in App blade**

    var channel = pusher.subscribe(&#39;notif-channel&#39;);
        channel.bind(&#39;order-event&#39;, function(data) {

            const obj = JSON.parse(JSON.stringify(data));
            const message = obj.message;
            
            blah blah blah
    }

</details>


# 答案1
**得分**: 1

用户和管理员应该在同一个频道上。例如,如果用户订阅了频道'order-channel-SetUserID'。
管理员应该向该频道发送消息,然后你应该在前端查找并在DOM上进行更改。

在你的控制器中,当你提交订单状态的更改时,运行带有频道名称的事件:

```php
event(new OrderEvent($user_id, '嗨,您的订单已处理!'));

现在你的事件应该类似于这样:

class OrderEvent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $user_id;
    public $message;

    public function __construct($user_id, $message)
    {
        $this->user_id  = $user_id;
        $this->message  = $message;
    }

    public function broadcastOn()
    {
        return new Channel('order-channel.' . $this->user_id);
    }

    public function broadcastAs()
    {
        return 'order-event';
    }
}

当然,你可以更改你的类名等等,我只是给出一个想法。

重要的是要通过与该用户相同的频道发送更改,否则你会对访问你网站的其他用户进行更改。

编辑

以下是你需要配置的其他内容。
在app/Providers/EventServiceProvider.php中

你需要将事件放在protected $listen中:

protected $listen = [
    Registered::class => [
        SendEmailVerificationNotification::class,
    ],
    OrderEvent::class => [
        OrderEventListener::class,
    ],
];

在app/Listeners中,你应该创建OrderEventListener.php并设置如下:

<?php

namespace App\Listeners;

use App\Events\OrderEvent;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Pusher;

class OrderEventListener
{
    public function __construct()
    {
        //
    }

    public function handle(OrderEvent $event)
    {
        $pusher = new Pusher(env('PUSHER_APP_KEY'), 
                  env('PUSHER_APP_SECRET'), env('PUSHER_APP_ID'), [
            'cluster' => env('PUSHER_APP_CLUSTER'),
            'useTLS' => true
        ]);

        $pusher->trigger($event->broadcastOn(),
        $event->broadcastAs(), $event->data);
    }
}

检查你的Pusher仪表板中的调试控制台?如果你能在那里看到事件触发,那么你只需要用JavaScript显示消息。如果没有事件正在运行,那么你的代码中可能有遗漏。

英文:

Both user and admin should be on the same channel. For example if user is subscribed for channel 'order-channel-SetUserID'.
Admin should send the message to that channel and you should look for it on the front end and make the changes on the DOM.

In your controller when you submit the changes of the status of the order run the event with the channel name

event(new OrderEvent($user_id, &#39;Hi, Your order is processed!&#39;));

Now your event should look similar to this:

class OrderEvent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $user_id;
    public $message;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct($user_id, $message)
    {
        $this-&gt;user_id  = $user_id;
        $this-&gt;message  = $message;
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        return new Channel(&#39;order-channel.&#39; . $this-&gt;user_id);
    }

    public function broadcastAs()
    {
        return &#39;order-event&#39;;
    }
}

Of course you can change your class Name etc... I'm just giving an idea.

it's important to send the changes on the same channel with this user or else you will make changes to other users that are visiting your website.

EDITED

Here is what else you need to configure.
In app/Providers/EventServiceProvider.php

You need to put the event in protected $listen

  protected $listen = [
        Registered::class =&gt; [
            SendEmailVerificationNotification::class,
        ],
        OrderEvent::class =&gt; [
            OrderEventListener::class,
        ],
    ];

In app/Listeners You should create OrderEventListener.php and set it up as follow:

&lt;?php
    
namespace App\Listeners;
use App\Events\OrderEvent;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Pusher;
    
    class OrderEventListener
        {
            /**
             * Create the event listener.
             *
             * @return void
             */
            public function __construct()
            {
                //
            }
        
            /**
             * Handle the event.
             *
             * @param  \App\Events\OrderEvent  $event
             * @return void
             */
            public function handle(OrderEvent $event)
            {
                $pusher = new Pusher(env(&#39;PUSHER_APP_KEY&#39;), 
                          env(&#39;PUSHER_APP_SECRET&#39;), env(&#39;PUSHER_APP_ID&#39;), [
                    &#39;cluster&#39; =&gt; env(&#39;PUSHER_APP_CLUSTER&#39;),
                    &#39;useTLS&#39; =&gt; true
                ]);
        
                $pusher-&gt;trigger($event-&gt;broadcastOn(),
                $event-&gt;broadcastAs(), $event-&gt;data);
            }

}

check your Debug Console in pusher dashboard? If you can see the event firing there all you need to do is show the message with javascript. If no event is running then something in your code is missing.

huangapple
  • 本文由 发表于 2023年2月6日 22:12:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/75362441.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定