Magento 2 Webhook: Hướng dẫn chi tiết kèm code ví dụ minh họa

Le Pham
Le Pham

Magento 2 Webhooks được sử dụng để thông báo khi nào một sự kiện quan trọng xảy ra, thường là bằng cách gửi thông báo dưới dạng tin nhắn đến một URL hoặc điểm cuối webhook được chỉ định. Điều này có thể thực sự hữu ích cho một số sự kiện nhất định, như khi khách hàng đặt hàng hoặc để lại nhận xét.

Nó cũng có thể là một cách thức tiện dụng để các nhà phát triển nhận được thông báo ngay lập tức khi có chuyện gì đó xảy ra, cung cấp cho họ thông tin để nhanh chóng xác định vị trí và khắc phục sự cố.

Trong bài viết này, chúng tôi sẽ chỉ cho bạn cách tạo một module cho phép cấu hình các webhooks của riêng bạn cho nền tảng Magento 2, sử dụng tính năng Webhooks đến từ Slack.

Magento 2 Webhook: Bắt đầu với Module

Trước khi tạo magento 2 webhook, chúng ta hãy bắt đầu bằng cách tạo một module trong thư mục / app / code của module Magento 2 của Inchoo. Trong ví dụ này, chúng ta sẽ sử dụng Inchoo làm nhà cung cấp module và đặt tên cho module Webhooks. Bạn có thể đặt tên cho chúng theo ý muốn vì đó là doanh nghiệp của bạn.

Chúng ta sẽ cần các thư mục và tập tin sau đây:

  • registration.php
  • /etc/module.xml
  • /etc/adminhtml/system.xml
  • /Model/Helper/Data.php
  • /Model / Webhook.php

registration.php

Đăng ký module trong hệ thống Magento. Sao chép mã sau vào tệp registration.php:

<?php

\Magento\Framework\Component\ComponentRegistrar::register(

    \Magento\Framework\Component\ComponentRegistrar::MODULE,

    ‘Inchoo_Webhooks’,

    __DIR__

);

module.xml

Khai báo tên và sự tồn tại của module. Sao chép mã sau vào file /etc/module.xml:

<?xml version=”1.0″?>

<config xmlns:xsi=”//www.w3.org/2001/XMLSchema-instance” xsi:noNamespaceSchemaLocation=”urn:magento:framework:Module/etc/module.xsd”>

    <module name=”Inchoo_Webhooks” setup_version=”1.0.0″>

    </module>

</config>

Cấu hình

Sau khi thiết lập module, chúng ta cần tạo cấu hình quản trị cho webhooks.

Sao chép mã sau vào tệp /etc/adminhtml/system.xml:

<?xml version=”1.0″?>

<config xmlns:xsi=”//www.w3.org/2001/XMLSchema-instance” xsi:noNamespaceSchemaLocation=”urn:magento:module:Magento_Config:etc/system_file.xsd”>

    <system>

        <section id=”system”>

            <group id=”inchoo_webhooks” sortOrder=”999″ translate=”label comment” showInDefault=”1″ showInWebsite=”0″ showInStore=”0″>

                <label>Webhook Notifications</label>

                <comment>

                    <![CDATA[To create Slack Incoming webhooks, visit <a href=”//api.slack.com/incoming-webhooks”>//api.slack.com/incoming-webhooks</a>]]>

                </comment>

                <field id=”enable_webhooks” translate=”label comment” type=”select” sortOrder=”5″ showInDefault=”1″ showInWebsite=”0″ showInStore=”0″>

                    <label>Enabled</label>

                    <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>

                </field>

                <field id=”incoming_webhook_url” translate=”label comment” type=”text” sortOrder=”10″ showInDefault=”1″ showInWebsite=”0″ showInStore=”0″>

                    <label>Incoming Webhook URL</label>

                    <depends>

                        <field id=”enable_webhooks”>1</field>

                    </depends>

                </field>

                <field id=”webhook_store_label” translate=”label comment” type=”text” sortOrder=”15″ showInDefault=”1″ showInWebsite=”0″ showInStore=”0″>

                    <label>Store Label</label>

                    <depends>

                        <field id=”enable_webhooks”>1</field>

                    </depends>

                </field>

                <field id=”webhook_message_prefix” translate=”label comment” type=”text” sortOrder=”20″ showInDefault=”1″ showInWebsite=”0″ showInStore=”0″>

                    <label>Message Prefix</label>

                    <depends>

                        <field id=”enable_webhooks”>1</field>

                    </depends>

                </field>

                <field id=”enable_stack_trace” translate=”label comment” type=”select” sortOrder=”25″ showInDefault=”1″ showInWebsite=”0″ showInStore=”0″>

                    <label>Stack Trace</label>

                    <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>

                    <depends>

                        <field id=”enable_webhooks”>1</field>

                    </depends>

                </field>

            </group>

        </section>

    </system>

</config>

Thao tác này có tác dụng thêm các trường cấu hình webhook vào giao diện quản trị Magento 2. Các trường này có thể được tìm thấy trong Stores -> Configuration -> Advanced -> Webhook Notifications và chúng sẽ trông như thế này:

Magento 2 Webhook: Bắt đầu với Module
  • Enabled: bật chức năng webhook
  • Incoming Webhook URL: URL webhook được cung cấp bởi ứng dụng Slack được định cấu hình
  • Store Label: nhãn sẽ được hiển thị trong thông báo webhook, nó sẽ chứa URL cửa hàng
  • Message Prefix: văn bản sẽ được đặt trước tin nhắn webhook, mã biểu tượng cảm xúc Slack có thể được sử dụng ở đây.
  • Stack Trace: nếu được bật, tin nhắn webhook sẽ hiển thị dấu vết của ngăn xếp sau tin nhắn được cung cấp.

Để tạo URL Webhook của riêng bạn, hãy truy cập //api.slack.com/messaging/webhooks và làm theo các bước ở đó. Bạn có thể sử dụng thêm các ứng dụng nào khác.

>>>> Xem thêm: Khóa học thực chiến PHP và Magento 2 – Khởi đầu chặng đường mới

Magento 2 Webhook: Tiếp theo là The Helper

Dữ liệu được nhập trong các trường cấu hình được lưu vào bảng core_config_data và chúng ta cần một cách để truy xuất thông tin đó. Sao chép mã sau vào tệp /Helper/Data.php:

<?php

declare(strict_types=1);

namespace Inchoo\Webhooks\Helper;

use Magento\Framework\App\Helper\AbstractHelper;

use Magento\Framework\App\Helper\Context;

use Magento\Framework\App\Config\ScopeConfigInterface;

use Magento\Framework\Exception\NoSuchEntityException;

use Magento\Store\Model\StoreManagerInterface;

/**

 * Class Data

 * @package Inchoo\Webhooks\Helper

 */

class Data extends AbstractHelper

{

    /**

     * @var StoreManagerInterface

     */

    private $storeManager;

    /**

     * Base path to Inchoo Webhooks configuration values

     */

    private const XML_PATH_WEBHOOKS = ‘system/inchoo_webhooks’;

    private const XML_WEBHOOKS_ENABLED = self::XML_PATH_WEBHOOKS . ‘/enable_webhooks’;

    private const XML_WEBHOOKS_STACK_TRACE_ENABLED = self::XML_PATH_WEBHOOKS . ‘/enable_stack_trace’;

    private const XML_WEBHOOKS_INCOMING_WEBHOOK_URL = self::XML_PATH_WEBHOOKS . ‘/incoming_webhook_url’;

    private const XML_WEBHOOKS_MESSAGE_PREFIX = self::XML_PATH_WEBHOOKS . ‘/webhook_message_prefix’;

    private const XML_WEBHOOKS_STORE_LABEL = self::XML_PATH_WEBHOOKS . ‘/webhook_store_label’;

    /**

     * Data constructor.

     *

     * @param Context $context

     * @param ScopeConfigInterface $scopeConfig

     * @param StoreManagerInterface $storeManager

     */

    public function __construct(

        Context $context,

        ScopeConfigInterface $scopeConfig,

        StoreManagerInterface $storeManager

    ) {

        $this->scopeConfig = $scopeConfig;

        $this->storeManager = $storeManager;

        parent::__construct($context);

    }

    /**

     * @return bool

     */

    public function isEnabled(): bool

    {

        return $this->scopeConfig->isSetFlag(self::XML_WEBHOOKS_ENABLED);

    }

    /**

     * @return bool

     */

    public function isStackTraceEnabled(): bool

    {

        return $this->scopeConfig->isSetFlag(self::XML_WEBHOOKS_STACK_TRACE_ENABLED);

    }

    /**

     * @return mixed

     */

    public function getIncomingWebhookURL()

    {

        return $this->scopeConfig->getValue(self::XML_WEBHOOKS_INCOMING_WEBHOOK_URL);

    }

    /**

     * @return mixed

     */

    public function getWebhookMessagePrefix()

    {

        return $this->scopeConfig->getValue(self::XML_WEBHOOKS_MESSAGE_PREFIX);

    }

    /**

     * @return mixed

     */

    public function getStoreLabel()

    {

        return $this->scopeConfig->getValue(self::XML_WEBHOOKS_STORE_LABEL);

    }

    /**

     * @return string

     * @throws NoSuchEntityException

     */

    public function getStoreName(): string

    {

        return $this->storeManager->getStore()->getName();

    }

    /**

     * @return mixed

     * @throws NoSuchEntityException

     */

    public function getStoreUrl()

    {

        return $this->storeManager->getStore()->getBaseUrl();

    }

}

Lớp này chứa các đường dẫn đến các giá trị đã lưu của chúng ta trong bảng core_config_data và một loạt các phương thức công khai mà chúng ta sẽ sử dụng trong lớp Webhook để lấy dữ liệu đó.

Magento 2 Webhook

Bây giờ cấu hình của chúng ta đã được thiết lập và chúng ta có các phương thức trợ giúp của riêng mình, chúng ta cần phải xác định lớp Webhook sẽ giữ logic xử lý tất cả dữ liệu và gửi thông báo đến URL webhook được định cấu hình.

Sao chép mã sau vào tệp /Model/Webhook.php:

<?php

declare(strict_types=1);

namespace Inchoo\Webhooks\Model;

use Inchoo\Webhooks\Helper\Data;

use Magento\Framework\Exception\NoSuchEntityException;

use Magento\Framework\HTTP\Adapter\CurlFactory;

use Psr\Log\LoggerInterface;

/**

 * Class Webhook

 * @package Inchoo\Webhooks\Model

 */

class Webhook

{

    /**

     * @var Data

     */

    private $webHookHelper;

    /**

     * @var CurlFactory

     */

    private $curlFactory;

    /**

     * @var LoggerInterface

     */

    private $logger;

    /**

     * Webhook constructor.

     * @param Data $webHookHelper

     * @param CurlFactory $curlFactory

     * @param LoggerInterface $logger

     */

    public function __construct(

        Data $webHookHelper,

        CurlFactory $curlFactory,

        LoggerInterface $logger

    ) {

        $this->webHookHelper = $webHookHelper;

        $this->curlFactory = $curlFactory;

        $this->logger = $logger;

    }

    /**

     * @param string $message

     * @return void

     * @throws NoSuchEntityException

     */

    public function sendWebhook(string $message): void

    {

        if (!$this->webHookHelper->isEnabled()) {

            return;

        }

        $url = $this->webHookHelper->getIncomingWebhookURL();

        $messagePrefix = $this->webHookHelper->getWebhookMessagePrefix();

        $storeName = $this->webHookHelper->getStoreName();

        $storeUrl = $this->webHookHelper->getStoreUrl();

        $storeLabel = $this->webHookHelper->getStoreLabel();

        $message = $messagePrefix ? $messagePrefix . ‘ ‘ . $message : $message;

        $text = ‘<‘ . $storeUrl . ‘|’ . $storeLabel . ‘> | ‘ . $storeName . ‘: ‘ . $message;

        $text = $this->webHookHelper->isStackTraceEnabled() ? $text . ‘ ‘ . $this->stackTrace() : $text;

        $header = [‘Content-type: application/json’];

        $body = json_encode([“text” =>  $text]);

        $client = $this->curlFactory->create();

        $client->addOption(CURLOPT_CONNECTTIMEOUT, 2);

        $client->addOption(CURLOPT_TIMEOUT, 3);

        $client->write(\Zend_Http_Client::POST, $url, ‘1.1’, $header, $body);

        $response = $client->read();

        $responseCode = \Zend_Http_Response::extractCode($response);

        if ($responseCode !== 200) {

            $this->logger->log(100, ‘Failed to send a message to the following Webhook: ‘ . $url);

        }

        $client->close();

    }

    /**

     * @return string

     */

    private function stackTrace(): string

    {

        $stackTrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);

        $trace = [];

        foreach ($stackTrace as $row => $data) {

            if (!array_key_exists(‘file’, $data) || !array_key_exists(‘line’, $data)) {

                $trace[] = “# <unknown>”;

            } else {

                $trace[] = “#{$row} {$data[‘file’]}:{$data[‘line’]} -> {$data[‘function’]}()”;

            }

        }

        return ‘“`’ .  implode(“\n“, $trace) . ‘“`’;

    }

}

Vậy là xong phần mã.

Lớp Webhook chứa hai phương thức, phương thức chung sendWebhook () và phương thức riêng stackTrace ().

Phương thức sendWebhook () là nơi xảy ra hầu hết các sự thay đổi. Chỉ có một đối số có thể được truyền cho phương thức này và đó là thông điệp mà chúng ta muốn gửi qua webhook, trong trường hợp của tôi, đến một kênh Slack. Ví dụ: chúng ta có thể gọi phương thức này trong một khối bắt và đối số được truyền cho nó có thể là thông báo ngoại lệ và mã trạng thái bị bắt.

Trong phương pháp, trước tiên chúng tôi kiểm tra xem webhooks có được bật trong cấu hình quản trị viên hay không. Nếu đúng, phương thức sẽ tiếp tục và truy xuất URL Webhook đến, tiền tố thông báo, tên cửa hàng, URL lưu trữ và nhãn lưu trữ bằng cách sử dụng các phương thức được xác định trong trình trợ giúp Data.php của chúng tôi.

Sau đó, tin nhắn được định dạng để bao gồm tiền tố tin nhắn, URL lưu trữ, nhãn cửa hàng và tên cửa hàng. Nếu Stack Trace được bật trong cấu hình, nó sẽ được xử lý bằng phương thức stackTrace () và được thêm vào văn bản cuối cùng.

Tiêu đề yêu cầu được đặt thành Content-type: application/json và văn bản cuối cùng được mã hóa json và được đặt trong phần nội dung yêu cầu.

Vì đang thực hiện cuộc gọi webhook một cách đồng bộ, chúng ta tạo một cá thể Curl và đặt thời gian chờ kết nối thành 2 giây và thời gian thực hiện thành 3 giây vì chúng ta không muốn yêu cầu thực thi quá lâu. Sau đó chúng ta sẽ gửi yêu cầu thông qua URL webhook và ghi lại mọi nỗ lực thất bại để gửi tin nhắn.

Kết thúc

Để hoàn tất mọi thứ, hãy sử dụng lệnh  bin/magento setup:upgrade  và định cấu hình webhook thông qua giao diện quản trị. Bây giờ bạn có thể thêm lớp Webhook đã tạo vào bất kỳ mã tùy chỉnh nào khác và dùng phương thức sendWebhook () của nó.

Thông báo webhook với Stack Trace được bật sẽ trông giống như thế này:

Magento 2 Webhook

Nếu bạn có bất kỳ câu hỏi hoặc vấn đề nào, xin vui lòng đừng ngần ngại để lại nhận xét bên dưới.

ĐỌC THÊM

Đăng ký theo dõi bản tin của chúng tôi để không bỏ sót bất kỳ thông tin hữu ích nào!

Lưu ý: Bằng việc cung cấp thông tin liên hệ cho chúng tôi, quý vị đã đồng ý nhận tin tức và các thông tin ưu đãi từ Magenest.