dive-be/laravel-expo-channel

此软件包已被放弃,不再维护。没有建议的替代软件包。

Laravel 的 Expo 通知通道

2.0.0 2024-03-15 09:54 UTC

This package is auto-updated.

Last update: 2024-04-18 07:48:32 UTC


README

重要

此通道已最终迁移到 其归属地(Laravel 通知通道项目),因此此存储库已被放弃。请从现在开始使用官方通道。

Social Card of Laravel Expo Channel

Expo 通知通道

Latest Version on Packagist GitHub Tests Action Status Total Downloads

Expo 通道用于向您的 React Native 应用推送通知。

内容

免责声明

此软件包目前不是 Laravel 通知通道 项目的部分,因为维护者似乎不活跃,且现有的 Expo 通道 从未完成,几乎已被放弃。此软件包遵守项目的所有约定(命名空间、消息创建等),因此未来可能的迁移只需替换 composer.json 中的软件包名称。

安装

您可以通过 composer 安装此软件包

composer require dive-be/laravel-expo-channel

额外安全(可选)

在 Expo 将它们发送给用户之前,您可以使用额外的 访问令牌 来要求发送任何推送通知。

如果您想使用此额外安全层,请将以下内容添加到您的 config/services.php 文件中

'expo' => [
    'access_token' => env('EXPO_ACCESS_TOKEN'),
],

使用

现在您可以在 Notificationvia() 方法中使用 expo 通道。

通知 / ExpoMessage

首先,您需要有一个需要发送给某人的 通知。有关生成通知的更多信息,请参阅 Laravel 文档

final class SuspiciousActivityDetected extends Notification
{
    public function toExpo($notifiable): ExpoMessage
    {
        return ExpoMessage::create('Suspicious Activity')
            ->body('Someone tried logging in to your account!')
            ->data($notifiable->only('email', 'id'))
            ->expiresAt(Carbon::now()->addHour())
            ->priority('high')
            ->playSound();
    }

    public function via($notifiable): array
    {
        return ['expo'];
    }
}

注意有关 Expo 消息请求格式的详细说明可在此处找到。

您还可以在 ExpoMessage 上应用条件而不破坏方法链

public function toExpo($notifiable): ExpoMessage
{
    return ExpoMessage::create('Suspicious Activity')
        ->body('Someone tried logging in to your account!')
        ->when($notifiable->wantsSound(), fn ($msg) => $msg->playSound())
        ->unless($notifiable->isVip(), fn ($msg) => $msg->normal(), fn ($msg) => $msg->high());
}

可通知的 / ExpoPushToken

接下来,您必须在您的 Notifiable 模型中设置一个 routeNotificationForExpo() 方法。

单播(单个设备)

此方法 必须 返回 ExpoPushToken 的实例或 null。示例

final class User extends Authenticatable
{
    use Notifiable;

    protected $casts = ['expo_token' => ExpoPushToken::class];

    public function routeNotificationForExpo(): ?ExpoPushToken
    {
        return $this->expo_token;
    }
}

警告如果返回 null,则不会发送任何通知。

注意有关模型转换的更多信息,请在此处找到。

多播(多个设备)

此方法 必须 返回一个 array<int, ExpoPushToken>Collection<int, ExpoPushToken> 的实例,具体实现取决于您的用例。示例

final class User extends Authenticatable
{
    use Notifiable;

    /**
    * @return Collection<int, ExpoPushToken>
    */
    public function routeNotificationForExpo(): Collection
    {
        return $this->devices->pluck('expo_token');
    }
}

警告如果返回空 Collection,则不会发送任何通知。

发送

一切准备就绪后,您只需通过调用即可简单发送通知

$user->notify(new SuspiciousActivityDetected());

验证

您应该有一个 HTTP 终端,它将给定的 ExpoPushToken 与经过身份验证的 User 关联,以便您可以发送推送通知。因此,我们还提供了一个自定义验证 ExpoPushTokenRule 类,您可以使用它来保护您的终端。示例

final class StoreDeviceRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'device_id' => ['required', 'string', 'min:2', 'max:255'],
            'token' => ['required', ExpoPushToken::rule()],
        ];
    }
}

模型铸造

ExpoChannel 预期您从您的 Notifiable 中返回一个 ExpoPushToken 实例。您可以通过将 ExpoPushToken 应用为自定义模型转换来实现这一点。示例

final class User extends Authenticatable
{
    use Notifiable;

    protected $casts = ['expo_token' => AsExpoPushToken::class];
}

此自定义值对象保证了推送令牌的完整性。您应该确保仅保存 有效的令牌

处理失败投递

不幸的是,Laravel 没有提供处理失败投递的 OOB 解决方案。然而,Laravel 提供了一个 NotificationFailed 事件,您可以通过此事件来挂钩失败的投递尝试。这在旧令牌不再有效且服务开始响应 DeviceNotRegistered 错误时尤其有用。

您可以注册一个事件监听器,该监听器监听此事件并处理相应的错误。示例

final readonly class HandleFailedExpoNotifications
{
    public function handle(NotificationFailed $event)
    {
        if ($event->channel !== 'expo') return;
        
        /** @var ExpoError $error */
        $error = $event->data;

        // Remove old token
        if ($error->type->isDeviceNotRegistered()) {
            $event->notifiable->update(['expo_token' => null]);
        } else {
            // do something else like logging...
        }
    }
}

NotificationFailed::$data 属性将包含一个 ExpoError 实例,该实例具有以下属性

final readonly class ExpoError
{
    private function __construct(
        public ExpoErrorType $type,
        public ExpoPushToken $token,
        public string $message,
    ) {}
}

Expo 消息请求格式

ExpoMessage 类包含以下方法来定义消息有效载荷。所有这些方法都对应于 Expo Push 文档 中定义的可用的有效载荷。

徽章(iOS)

设置显示在应用程序图标上的徽章中的数字。

badge(int $value)

注意 该值必须大于或等于 0。

正文

设置要显示在通知中的消息正文。

body(string $value)
text(string $value)

注意 该值不能为空。

类别 ID

设置与通知关联的通知类别 ID。

categoryId(string $value)

注意 该值不能为空。

频道 ID(Android)

设置通过该通知显示通知的通知频道 ID。

channelId(string $value)

注意 该值不能为空。

JSON 数据

设置消息的 JSON 数据。

data(Arrayable|Jsonable|JsonSerializable|array $value)

警告 我们使用 Gzip(如果 ext-zlib 可用)压缩超过 1 KiB 的 JSON 有效载荷。虽然技术上可以发送超过 4 KiB 的数据,但这不是推荐的。

过期时间

设置消息的过期时间。与 TTL 具有相同的效果。

expiresAt(DateTimeInterface|int $value)

警告 如果两者都设置了,则 TTL 优先。

注意 该值必须在将来。

可变内容(iOS)

设置通知是否可以被客户端应用程序拦截。

mutableContent(bool $value = true)

通知声音(iOS)

当接收者收到通知时播放默认的通知声音。

playSound()

警告 不支持自定义声音。

优先级

设置消息的投递优先级。

priority(string $value)
default()
normal()
high()

注意 该值必须是 defaultnormalhigh

副标题(iOS)

设置在通知标题下方显示的副标题。

subtitle(string $value)

注意 该值不能为空。

标题

设置要在通知中显示的标题。

title(string $value)

注意 该值不能为空。

TTL(存活时间)

设置消息可能被重新投递的秒数。

ttl(int $value)
expiresIn(int $value)

警告 如果两者都设置了,则 expiration 优先。

注意 该值必须大于 0。

测试

composer test

变更日志

请参阅 变更日志 了解最近发生了哪些变化。

贡献

请参阅 贡献指南 了解详细信息。

安全

如果您发现任何与安全相关的问题,请通过电子邮件 oss@dive.be 而不是使用问题跟踪器。

致谢

许可

MIT 许可证(MIT)。有关更多信息,请参阅 许可证文件