Hôm nay mình sẽ hướng dẫn cho các bạn cách tạo một webhook mechanism cho riêng mình. từ lâu chúng ta đã biểt đến và dùng chức năng webhook của github, facebook … .Đại loại là họ sẽ cho mình nhập 1 Payload URL và chọn sự kiện để khi có sự kiện đó thì github cũng send http request đến Payload URL của người dùng.
Tương tự vậy, ở demo nay chúng ta sẽ cho phép người dùng nhập webhook url của họ. và khi có 1 sự kiện nào đó trên hệ thống chúng ta thì hệ thống cũng tiến hành send http request đến url của họ (request gồm body và header).
Webhook là gì?
Cài đặt Dependencies
Đầu tiên chúng ta cần cài đặt package để cho việc gửi HTTP request. Ở đây mình dùng thư viện khá phổ biến là Guzzle:
1
composer require guzzlehttp/guzzle:~6.0
Migrate dữ liệu
Tiếp theo chúng ta tạo bảng user. ở ví dụ demo này thì mình sẽ lưu name, email, password, api_token và đặc biệt có thêm trường webhook_url đây chính là enpoint của người dùng khi đăng ký Webhook End Point trên hệ thống của chúng ta.
/** * @param Notifiable $notifiable * @param Notification $notification * @throws WebHookFailedException */ publicfunctionsend($notifiable, Notification $notification) { if (method_exists($notification, 'toWebhook')) { $body = (array) $notification->toWebhook($notifiable); } else { $body = $notification->toArray($notifiable); } $timestamp = now()->timestamp; $token = str_random(16); // Tạo header cho request webhook . cái này để người dùng có thể xác minh request gửi lên là từ hệ thống của chúng ta mà không phải từ hệ thông khác $headers = [ 'timestamp' => $timestamp, 'token' => $token, 'signature' => hash_hmac( 'sha256', $token . $timestamp, $notifiable->getSigningKey() ), ]; // Tiếp theo chúng ta tạo 1 request sử dụng GuzzleHttp để gửi request $request = new Request('POST', $notifiable->getWebhookUrl(), $headers, json_encode($body));
try { $response = $this->client->send($request); // kiểm tra nếu không nhận được status code = 200 thì sẽ báo lỗi if ($response->getStatusCode() !== 200) { thrownew WebHookFailedException('Webhook received a non 200 response'); } // Lưu lại log $this->logger->debug('Webhook successfully posted to '. $notifiable->getWebhookUrl());