Hướng dẫn gửi Push notification với Urbanship

  • June 23, 2020
  • 811
Mình đã hướng dẫn các bạn viết một service để gửi push notification sử dụng firebase. Hôm nay mình sẽ giới thiệu thêm gửi push notification với Urbanship

Làm thế nào để gửi push notification với urbanship

Khác với Firebase, Urbanship gửi push notification dựa vào channel_id. Channel id cũng được đảm bảo là unique. Server sẽ lưu channel_id vào bảng channels

+--------------+---------------------+------+-----+---------+----------------+
| Field        | Type                | Null | Key | Default | Extra          |
+--------------+---------------------+------+-----+---------+----------------+
| id           | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| user_id      | bigint(20) unsigned | YES  | MUL | NULL    |                |
| channel_id | varchar(255)        | NO   |     | NULL    |                |
| device_id    | varchar(255)        | YES  | MUL | NULL    |                |
| device_type  | varchar(25)         | NO   |     | ios     |                |
| active       | tinyint(1)          | NO   | MUL | 1       |                |
| created_at   | timestamp           | YES  |     | NULL    |                |
| updated_at   | timestamp           | YES  |     | NULL    |                |
+--------------+---------------------+------+-----+---------+----------------+

Hướng dẫn gửi push với laravel

Tạo một Urbanship service

 App/Service/UrbanshipService.php


<?php

namespace App\Services;

use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\RequestOptions;
use Log;

class UrbanshipService
{
    /** @var $client Client */
    protected $client;

    /** @var $baseUrl string */
    protected $baseUrl;

    public function __construct()
    {
        $this->baseUrl = 'https://go.urbanairship.com';
        $this->client  = new Client([
            'base_uri' => $this->baseUrl
        ]);
    }

    private function getToken()
    {
        $appKey       = config('urbanship.app_key');
        $masterSecret = config('urbanship.master_secret');
        $token        = base64_encode($appKey . ":" . $masterSecret);

        return $token;
    }

    /**
     * @param $data
     * @return bool
     */
    public function send($data)
    {
        $body = [
            RequestOptions::JSON    => $data,
            RequestOptions::HEADERS => $this->getHeaders()
        ];

        try {
            $response = $this->client->post('api/push', $body);

            if ($response->getStatusCode() == '202') {
                return true;
            }

            return false;
        } catch (ClientException $e) {
            Log::error($e->getMessage());

            return false;
        }
    }

    private function getHeaders($headers = [])
    {
        $defaultHeaders = [
            'Authorization' => 'Basic ' . $this->getToken(),
            'Accept'        => 'application/vnd.urbanairship+json; version=3;',
            'Content-Type'  => 'application/json',
        ];

        return array_merge($defaultHeaders, $headers);
    }
}

Tạo một fire config

Chứa các thông tin liên quan đến urbanship

config/urbanship.php


<?php

return [
    'app_key'       => env('URBAN_APP_KEY'),
     'master_secret' => env('URBAN_MASTER_SECRET'),
     'vap_id_public_key' => env('URBAN_VAP_ID_PUBLIC_KEY'),
     'token' => env('URBAN_TOKEN')
];

Viết một service để gửi push

App/Services/NotificationService.php


<?php

namespace App\Services;

use App\Entities\Channel;
use App\Services\UrbanshipService;
use Log;

class NotificationService
{

    protected $urbanShip;

    public function __construct()
    {
        $this->urbanShip = app(UrbanshipService::class);
    }

    public function sendPush($userId, $message, $title = null, $extra = [])
    {
        $channels = Channel::where(
            [
                ['user_id', '=', $userId],
                ['active', '=', Channel::$active['active']],
            ]
        )->get();

        if ($channels->isEmpty()) {
            Log::error('[SEND_PUSH] EMPTY CHANNEL');
            return false;
        }

        $audiences = [];
        foreach ($channels as $channel) {
            $channelKeyStr = $channel->device_type . "_channel";
            $audiences[] = [$channelKeyStr => $channel->channel_id];
        }

        $data = [
            'audience' => [
                'or' => $audiences
            ],
            'device_types' => ['ios', 'android'],
            'notification' => [
                'alert' => $message,
                'ios' => [
                    'sound' => 'boop',
                    'badge' => 1 // số message chưa đọc
                ],
                'android' => [
                    'sound' => 'boop'
                ]
            ]
        ];

        if ($title) {
            $data['notification']['ios']['title'] = $title;
            $data['notification']['android']['title'] = $title;
        }
        if (!empty($extra)) {
            $data['notification']['ios']['extra'] = $extra;
            $extra['badge_count'] = 1; // số message chưa đọc
            $data['notification']['android']['extra'] = $extra;
        }

        return $this->urbanShip->send($data);
    }

    public function pushNotificationToWeb(string $title, string $body, string $url)
    {
        $channels = Channel::where(
            [
                ['device_type', '=', 'web'],
                ['active', '=', Channel::$active['active']],
            ]
        )->get();
        
        if ($channels->isEmpty()) {
            Log::error('[SEND_PUSH] EMPTY CHANNEL');
            return false;
        }

        $audiences = [];
        foreach ($channels as $channel) {
            $channelKeyStr = $channel->device_type . "_channel";
            $audiences[] = [$channelKeyStr => $channel->channel_id];
        }

        $data = [
            'audience' => [
                'or' => $audiences
            ],
            'device_types' => ['web'],
            'notification' => [
                'alert' => ($body) ?: '',
                'web' => [
                    'title' => ($title) ?: ''
                ],
                'actions' => [
                    'open' => [
                        'type' => 'url',
                        'content' => $url
                    ],
                ],
            ]
        ];

        return $this->urbanShip->send($data);
    }
}

Trên đây là toàn bộ hướng dẫn về push notification với Urbanship thông qua laravel. Chúc ae gửi được push thành công nhé!