From dbcb4eb74924ac5493699a08003d149a6eb14722 Mon Sep 17 00:00:00 2001 From: "@ChristelLoftus" <christel@bob.co.za> Date: Wed, 2 Oct 2024 15:44:00 +0200 Subject: [PATCH] triggerWebhookTest --- Model/Carrier/BobGo.php | 87 +++++++++++++++++++++++++++++++ Model/Carrier/UData.php | 2 +- Observer/ConfigChangeObserver.php | 20 +++++++ Observer/OrderCreateWebhook.php | 1 + Observer/OrderWebhookBase.php | 24 +++++++-- etc/adminhtml/system.xml | 16 ++++++ 6 files changed, 145 insertions(+), 5 deletions(-) diff --git a/Model/Carrier/BobGo.php b/Model/Carrier/BobGo.php index 386e4cb..51cf36b 100644 --- a/Model/Carrier/BobGo.php +++ b/Model/Carrier/BobGo.php @@ -864,6 +864,11 @@ class BobGo extends AbstractCarrierOnline implements \Magento\Shipping\Model\Car return UData::RATES_ENDPOINT; } + private function getWebhookUrl(): string + { + return UData::WEBHOOK_URL; + } + /** * Perform API Request to Bob Go API and return response. * @@ -1310,4 +1315,86 @@ class BobGo extends AbstractCarrierOnline implements \Magento\Shipping\Model\Car } return false; } + + public function isWebhookEnabled(): bool + { + $enabled = $this->scopeConfig->getValue( + 'carriers/bobgo/enable_webhooks', + \Magento\Store\Model\ScopeInterface::SCOPE_STORE + ); + + // Cast the value to a boolean + return filter_var($enabled, FILTER_VALIDATE_BOOLEAN); + } + + + public function triggerWebhookTest(): bool + { + $webhookKey = $this->scopeConfig->getValue( + 'carriers/bobgo/webhook_key', + \Magento\Store\Model\ScopeInterface::SCOPE_STORE + ); + + $isEnabled = $this->scopeConfig->getValue( + 'carriers/bobgo/enable_webhooks', + \Magento\Store\Model\ScopeInterface::SCOPE_STORE + ); + + // Convert the string to a boolean value + $isEnabled = filter_var($isEnabled, FILTER_VALIDATE_BOOLEAN); + +// if (!$webhookKey) { +// $this->_logger->error('Webhook key not configured.'); +// return false; +// } + + $storeId = strval($this->_storeManager->getStore()->getId()); + + $payload = [ + 'event' => 'webhook_validation', + 'channel_identifier' => $this->getBaseUrl(), + 'store_id' => $storeId, + 'webhooks_enabled' => $isEnabled, + ]; + + try { + // Generate the HMAC-SHA256 hash as raw binary data + $rawSignature = hash_hmac('sha256', $storeId, $webhookKey, true); + // Encode the binary data in Base64 + $signature = base64_encode($rawSignature); + // Set headers and post the data + $this->curl->addHeader('Content-Type', 'application/json'); + $this->curl->addHeader('X-M-Webhook-Signature', $signature); + + $payloadJson = json_encode($payload); + $this->_logger->info('Webhooks payload: ' . $payloadJson); + if ($payloadJson === false) { + throw new \RuntimeException('Failed to encode payload to JSON.'); + } + + $this->curl->addHeader('Content-Type', 'application/json'); + $this->curl->post($this->getWebhookUrl(), $payloadJson); + $statusCode = $this->curl->getStatus(); + $this->_logger->info('Webhooks statuscode: ' . $statusCode); + $responseBody = $this->curl->getBody(); + $this->_logger->info('Webhooks response: ' . $responseBody); + + $response = json_decode($responseBody, true); + + if ($statusCode == 200 && isset($response['success']) && $response['success'] === true) { + $this->_logger->info('Webhook validation successful.'); +// throw new LocalizedException(__('Rates received but id field is empty or invalid.')); + return true; + } else { + $this->_logger->error('Webhook validation failed: ' . ($response['message'] ?? 'Unknown error')); +// throw new LocalizedException(__('Rates received but id field is empty or invalid.')); + return false; + } + } catch (\Exception $e) { + $this->_logger->error('Webhook validation exception: ' . $e->getMessage()); +// throw new LocalizedException(__('Rates received but id field is empty or invalid.')); + return false; + } + } + } diff --git a/Model/Carrier/UData.php b/Model/Carrier/UData.php index adf83a2..a7e5d2e 100644 --- a/Model/Carrier/UData.php +++ b/Model/Carrier/UData.php @@ -26,5 +26,5 @@ class UData * * @var string */ - public const WEBHOOK_URL = 'https://api.dev.bobgo.co.za/webhook/channel/magento'; + public const WEBHOOK_URL = 'https://api.dev.bobgo.co.za/webhook/channel'; } diff --git a/Observer/ConfigChangeObserver.php b/Observer/ConfigChangeObserver.php index 1b6c072..528dd82 100644 --- a/Observer/ConfigChangeObserver.php +++ b/Observer/ConfigChangeObserver.php @@ -52,6 +52,7 @@ class ConfigChangeObserver implements ObserverInterface { $changedPaths = $observer->getEvent()->getData('changed_paths'); + // Test for rates at checkout if (is_array($changedPaths) && in_array('carriers/bobgo/active', $changedPaths)) { if ($this->bobGo->isActive()) { $result = $this->bobGo->triggerRatesTest(); @@ -70,5 +71,24 @@ class ConfigChangeObserver implements ObserverInterface } } } + + // Test for webhooks + if (is_array($changedPaths) && in_array('carriers/bobgo/enable_webhooks', $changedPaths)) { +// if ($this->bobGo->isWebhookEnabled()) { + $this->logger->info('Webhooks test start: '); + $result = $this->bobGo->triggerWebhookTest(); + $this->logger->info('Webhooks test end: ' . $result); + + if ($result) { + $this->messageManager->addSuccessMessage( + __('Webhook validation successful.') + ); + } else { + $this->messageManager->addErrorMessage( + __('Webhook validation failed. Please check the webhook key and try again.') + ); + } +// } + } } } diff --git a/Observer/OrderCreateWebhook.php b/Observer/OrderCreateWebhook.php index 74f1ce4..f605801 100644 --- a/Observer/OrderCreateWebhook.php +++ b/Observer/OrderCreateWebhook.php @@ -15,5 +15,6 @@ class OrderCreateWebhook extends OrderWebhookBase // Extract order data and send to the webhook URL $this->sendWebhook($order); + $this->logger->info('Webhooks sent'); } } diff --git a/Observer/OrderWebhookBase.php b/Observer/OrderWebhookBase.php index eeb106e..db27d61 100644 --- a/Observer/OrderWebhookBase.php +++ b/Observer/OrderWebhookBase.php @@ -3,6 +3,7 @@ namespace BobGroup\BobGo\Observer; use BobGroup\BobGo\Model\Carrier\UData; +use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\Event\ObserverInterface; use Magento\Framework\HTTP\Client\Curl; use Magento\Store\Model\StoreManagerInterface; @@ -13,18 +14,29 @@ abstract class OrderWebhookBase implements ObserverInterface protected Curl $curl; protected LoggerInterface $logger; protected StoreManagerInterface $storeManager; + protected ScopeConfigInterface $scopeConfig; - public function __construct(LoggerInterface $logger, Curl $curl, StoreManagerInterface $storeManager) + public function __construct(LoggerInterface $logger, Curl $curl, StoreManagerInterface $storeManager, ScopeConfigInterface $scopeConfig) { $this->logger = $logger; $this->curl = $curl; $this->storeManager = $storeManager; + $this->scopeConfig = $scopeConfig; } protected function sendWebhook($order) { + $enabled = $this->scopeConfig->getValue('carriers/bobgo/enable_webhooks', \Magento\Store\Model\ScopeInterface::SCOPE_STORE); + + // Return early if webhooks is disabled + if (!$enabled) { + $this->logger->info('Webhooks are disabled. Exiting webhook process for order: ' . $order->getIncrementId()); + return; + } + // Webhook URL $url = $this->getWebhookUrl(); + $this->logger->info('Webhooks url: ' . $url); $storeId = $this->getStoreId(); @@ -54,14 +66,17 @@ abstract class OrderWebhookBase implements ObserverInterface // Send the webhook $this->makeHttpPostRequest($url, $data, $storeId); + $this->logger->info('Webhooks sent'); } private function makeHttpPostRequest($url, $data, $storeId) { - // Generate the signature using a secret key and the payload (example using HMAC SHA256) - $secretKey = 'KaJGW2cxx1-6z_qjGhSq5Hj4qh_OXl0R1tUPurVs66A'; + // Generate the signature using the webhook key saved in config + $webhookKey = $this->scopeConfig->getValue('carriers/bobgo/webhook_key', \Magento\Store\Model\ScopeInterface::SCOPE_STORE); + $this->logger->info('Webhooks - key: ' . $webhookKey); +// $secretKey = 'KaJGW2cxx1-6z_qjGhSq5Hj4qh_OXl0R1tUPurVs66A'; // Generate the HMAC-SHA256 hash as raw binary data - $rawSignature = hash_hmac('sha256', $storeId, $secretKey, true); + $rawSignature = hash_hmac('sha256', $storeId, $webhookKey, true); // Encode the binary data in Base64 $signature = base64_encode($rawSignature); @@ -79,6 +94,7 @@ abstract class OrderWebhookBase implements ObserverInterface // Set headers and post the data $this->curl->addHeader('Content-Type', 'application/json'); $this->curl->post($url, $payloadJson); + $this->logger->info('Webhooks payload: ' . $payloadJson); } private function getWebhookUrl(): string diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index 410c2c2..3f4b31f 100644 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -28,6 +28,22 @@ <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> <comment>Displays the delivery timeframe and additional service level description, as configured on Bob Go.</comment> </field> + + <!-- Enable Webhooks Checkbox --> + <field id="enable_webhooks" translate="label" type="select" sortOrder="8" showInDefault="1" showInWebsite="1" showInStore="0"> + <label>Enable webhooks</label> + <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> + <comment>Enable or disable the webhook functionality for Bob Go.</comment> + </field> + + <!-- Webhook Key Input Field --> + <field id="webhook_key" translate="label" type="text" sortOrder="9" showInDefault="1" showInWebsite="1" showInStore="0"> + <label>Webhook key</label> + <comment>Enter the webhook key for authentication.</comment> + <depends> + <field id="enable_webhooks">1</field> + </depends> + </field> </group> </section> </system> -- GitLab