BxDolAIProviderShopifyAdmin.php 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. <?php defined('BX_DOL') or die('hack attempt');
  2. /**
  3. * Copyright (c) UNA, Inc - https://una.io
  4. * MIT License - https://opensource.org/licenses/MIT
  5. *
  6. * @defgroup UnaCore UNA Core
  7. * @{
  8. */
  9. /*
  10. * Login for Owner/Collaborator account:
  11. * https://admin.shopify.com/store/your_shop/
  12. *
  13. * Integration:
  14. * 0. Custom apps creation guide (for a shop Owner/Collaborator, not a Partner):
  15. * https://help.shopify.com/en/manual/apps/app-types/custom-apps
  16. *
  17. * 1. Make authenticated requests to the REST Admin API:
  18. * https://shopify.dev/docs/apps/auth/admin-app-access-tokens
  19. *
  20. * 2. REST Admin API reference:
  21. * https://shopify.dev/docs/api/admin-rest
  22. *
  23. * 3. REST Admin API -> Product
  24. * https://shopify.dev/docs/api/admin-rest/2023-10/resources/product
  25. *
  26. * 4. REST Admin API -> Order
  27. * https://shopify.dev/docs/api/admin-rest/2023-10/resources/order
  28. *
  29. */
  30. class BxDolAIProviderShopifyAdmin extends BxDolAIProvider
  31. {
  32. public static $PROVIDER_NAME = 'shopify_admin';
  33. protected $_sShopDomain;
  34. protected $_sAccessToken;
  35. protected $_sEndpoint;
  36. protected $_sStorefront;
  37. public function __construct($aProvider)
  38. {
  39. $this->_sProviderName = self::$PROVIDER_NAME;
  40. parent::__construct($aProvider);
  41. $this->_sShopDomain = $this->getOption('shop_domain');
  42. $this->_sAccessToken = $this->getOption('access_token');
  43. $this->_sEndpoint = "https://{$this->_sShopDomain}/admin/api/2023-10/";
  44. $this->_sStorefront = "https://{$this->_sShopDomain}/";
  45. }
  46. public function getEntry($sId)
  47. {
  48. $sProduct = $this->call('products/' . $sId . '.json', [
  49. 'fields' => 'id,title,handle,body_html,tags,variants',
  50. ], 'get');
  51. if(empty($sProduct))
  52. return [];
  53. $aProduct = json_decode($sProduct, true);
  54. if(empty($aProduct) || !is_array($aProduct) || empty($aProduct['product']))
  55. return [];
  56. return $aProduct['product'];
  57. }
  58. public function getOptionWebhookUrl()
  59. {
  60. return bx_append_url_params(BX_DOL_URL_ROOT . 'agents.php', [
  61. 'p' => $this->_iId,
  62. 'a' => 'webhook'
  63. ]);
  64. }
  65. public function processActionWebhook()
  66. {
  67. $sData = @file_get_contents('php://input');
  68. $this->_log(json_decode($sData, true));
  69. $sHmacHeader = isset($_SERVER['HTTP_X_SHOPIFY_HMAC_SHA256']) ? $_SERVER['HTTP_X_SHOPIFY_HMAC_SHA256'] : '';
  70. if(!$this->_verifyWebhook($sData, $sHmacHeader)) {
  71. http_response_code(401);
  72. return;
  73. }
  74. $oAi = BxDolAI::getInstance();
  75. $aAutomators = $oAi->getAutomatorsWebhook($this->_iId);
  76. foreach($aAutomators as $aAutomator)
  77. $oAi->callAutomator(BX_DOL_AI_AUTOMATOR_WEBHOOK, [
  78. 'automator' => $aAutomator
  79. ]);
  80. http_response_code(200);
  81. }
  82. public function call($sRequest, $aParams, $sMethod = 'post-json', $aHeaders = [])
  83. {
  84. $aHeaders[] = 'Content-Type: application/json';
  85. if(!empty($this->_sAccessToken))
  86. $aHeaders[] = 'X-Shopify-Access-Token: ' . $this->_sAccessToken;
  87. else
  88. $aHeaders[] = 'Authorization: Basic ' . base64_encode($this->_sApiKey . ':' . $this->_sApiSecretKey);
  89. $sResponse = bx_file_get_contents($this->_sEndpoint . $sRequest, $aParams, $sMethod, $aHeaders);
  90. if(empty($sResponse))
  91. return false;
  92. $aResponse = json_decode($sResponse, true);
  93. if(empty($aResponse) || !is_array($aResponse))
  94. return false;
  95. return $aResponse;
  96. }
  97. /**
  98. * Internal methods.
  99. */
  100. protected function _dateI2S($iTimestamp)
  101. {
  102. return date("Y-m-d", $iTimestamp);
  103. }
  104. protected function _verifyWebhook($sData, $sHmacHeader)
  105. {
  106. $sHmacCalc = base64_encode(hash_hmac('sha256', $sData, $this->getOption('secret_key'), true));
  107. return hash_equals($sHmacCalc, $sHmacHeader);
  108. }
  109. }