1

在我的带有 Laravel 的应用程序中,后端用户可以互相发送消息。

我想在新收件箱消息上向应用程序用户发送推送通知,但只有在用户尚未阅读此消息时我才需要发送消息。

所以我是这样看的

  1. 在发送的每条消息上,我需要在 1 分钟后安排 Laravel 通知
  2. 如果用户已经收到此消息,我需要取消此通知

如何关闭 Laravel 中的预定通知?这种方法现在可行吗?

类扩展通知

public function via($notifiable)
{
    if($this->dontSend($notifiable)) {
        return [];
    }
    return ['mail'];
}

public function dontSend($notifiable)
{
    return $this->appointment->status === 'cancelled';
} 

也许有更方便的方法来处理它?例如,每次发送推送,但如果它已经启动,以某种方式从应用程序中显示它?

4

1 回答 1

1

一种方法是这样的;

  • 在触发通知之前,请sha1使用user_id. 假设它是SgiA7EfBQBFQK3pjRWtaxB1CkSf7gf4lSixvei3jU3ydHJ39ZGjhhdUUCnHRno3C。将其发送到通知。通知和消息将同时发送,但通知会有一分钟的延迟。
$identifier = Str::random(64);
$delay = now()->addMinute();
$user->notify((new MyNotification($identifier))->delay($delay));
// send a request that contains identifier.
  • 您将其设置为 TTL 为 2 分钟的 Redis。如果不采取行动,它就会消失。
Redis::set('SgiA7EfBQBFQK3pjRWtaxB1CkSf7gf4lSixvei3jU3ydHJ39ZGjhhdUUCnHRno3C', 1, 120);
  • 在向用户发送消息时,将此标识符附加到消息中。当用户阅读该消息时,您使用所有参数 + 标识符向您的 /read 端点发出请求。
  • 收到请求后,从 Redis 中删除密钥。(用户收到消息)
Redis::del('SgiA7EfBQBFQK3pjRWtaxB1CkSf7gf4lSixvei3jU3ydHJ39ZGjhhdUUCnHRno3C');
  • 在 Notification 类中,实现一个小方法来检查键是否存在于 Redis 中。
Redis::exists('SgiA7EfBQBFQK3pjRWtaxB1CkSf7gf4lSixvei3jU3ydHJ39ZGjhhdUUCnHRno3C');
class MyNotification extends BaseNotification
{
    use Queueable;

    private $identifier;

    public function __construct($identifier)
    {
        $this->identifier = $identifier;
    }

    public function via()
    {
        return $this->isValid() ? ['mail'] : [];
    }

    public function isValid()
    {
        return Redis::exists($this->identifier);
    }

    public function toMail()
    {
        // details..
    }
}

它不一定是 Redis,但它非常适合这种键/值结构。

于 2020-07-03T22:43:03.173 回答