PageRenderTime 87ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/messageservice/lib/sender/sms/smslineby.php

https://gitlab.com/alexprowars/bitrix
PHP | 335 lines | 277 code | 53 blank | 5 comment | 17 complexity | 5ee646d31b860f95ca2f6f6d3ddb4d7a MD5 | raw file
  1. <?php
  2. namespace Bitrix\MessageService\Sender\Sms;
  3. use Bitrix\Main\Error;
  4. use Bitrix\Main\Localization\Loc;
  5. use Bitrix\Main\ModuleManager;
  6. use Bitrix\Main\Result;
  7. use Bitrix\Main\Web\HttpClient;
  8. use Bitrix\Main\Web\Json;
  9. use Bitrix\MessageService\Sender;
  10. use Bitrix\MessageService\Sender\Result\MessageStatus;
  11. use Bitrix\MessageService\Sender\Result\SendMessage;
  12. use Bitrix\MessageService;
  13. Loc::loadMessages(__FILE__);
  14. class SmsLineBy extends Sender\BaseConfigurable
  15. {
  16. public const ID = 'smslineby';
  17. const JSON_API_URL = 'https://api.smsline.by/v3/';
  18. public static function isSupported()
  19. {
  20. return ModuleManager::isModuleInstalled('b24network');
  21. }
  22. public function getId()
  23. {
  24. return static::ID;
  25. }
  26. public function getName()
  27. {
  28. return 'SMS-line';
  29. }
  30. public function getShortName()
  31. {
  32. return 'smsline.by';
  33. }
  34. public function getFromList()
  35. {
  36. $from = $this->getOption('from_list');
  37. return is_array($from) ? $from : [];
  38. }
  39. public function isRegistered()
  40. {
  41. return (
  42. $this->getOption('login') !== null
  43. &&
  44. $this->getOption('api_key') !== null
  45. );
  46. }
  47. public function register(array $fields)
  48. {
  49. $login = (string) $fields['login'];
  50. $key = (string) $fields['api_key'];
  51. $result = $this->sendGetRequest('balance/packets', $this->makeSignature('balancepackets', $key), $login);
  52. if ($result->isSuccess())
  53. {
  54. $this->setOption('login', $login);
  55. $this->setOption('api_key', $key);
  56. }
  57. return $result;
  58. }
  59. /**
  60. * @return array [
  61. * 'login' => ''
  62. * ]
  63. */
  64. public function getOwnerInfo()
  65. {
  66. return array(
  67. 'login' => $this->getOption('login'),
  68. );
  69. }
  70. public function getExternalManageUrl()
  71. {
  72. return 'https://mobilemarketing.by/login/';
  73. }
  74. public function sendMessage(array $messageFields)
  75. {
  76. if (!$this->canUse())
  77. {
  78. $result = new SendMessage();
  79. $result->addError(new Error('Service is unavailable'));
  80. return $result;
  81. }
  82. $message = [
  83. 'target' => $messageFields['MESSAGE_FROM'],
  84. 'msisdn' => str_replace('+', '', $messageFields['MESSAGE_TO']),
  85. 'text' => $messageFields['MESSAGE_BODY'],
  86. 'callback_url' => $this->getCallbackUrl()
  87. ];
  88. $result = new SendMessage();
  89. $apiResult = $this->sendPostRequest('messages/single/sms', $message);
  90. $result->setServiceRequest($apiResult->getHttpRequest());
  91. $result->setServiceResponse($apiResult->getHttpResponse());
  92. if (!$apiResult->isSuccess())
  93. {
  94. $result->addErrors($apiResult->getErrors());
  95. }
  96. else
  97. {
  98. $resultData = $apiResult->getData();
  99. $smsData = $resultData['message'];
  100. $smsId = $smsData['id_message'];
  101. if (!$smsId)
  102. {
  103. $result->addError(new Error($this->getErrorMessage(-1000)));
  104. }
  105. else
  106. {
  107. $result->setExternalId($smsId);
  108. $result->setAccepted();
  109. }
  110. }
  111. return $result;
  112. }
  113. public function getMessageStatus(array $messageFields)
  114. {
  115. $result = new MessageStatus();
  116. $result->setId($messageFields['ID']);
  117. $result->setExternalId($messageFields['EXTERNAL_ID']);
  118. if (!$this->canUse())
  119. {
  120. $result->addError(new Error('Service is unavailable'));
  121. return $result;
  122. }
  123. $apiResult = $this->sendGetRequest('messages/'.$result->getExternalId());
  124. if (!$apiResult->isSuccess())
  125. {
  126. $result->addErrors($apiResult->getErrors());
  127. }
  128. else
  129. {
  130. $resultData = $apiResult->getData();
  131. $smsData = $resultData['message'];
  132. if (!$smsData)
  133. {
  134. $result->addError(new Error($this->getErrorMessage(-1000)));
  135. }
  136. $result->setStatusText($smsData['state']['name']);
  137. $result->setStatusCode(self::resolveStatus($smsData['state']['state']));
  138. }
  139. return $result;
  140. }
  141. public static function resolveStatus($serviceStatus)
  142. {
  143. $status = parent::resolveStatus($serviceStatus);
  144. switch ($serviceStatus)
  145. {
  146. case 'seen':
  147. return MessageService\MessageStatus::READ;
  148. break;
  149. case 'delivered':
  150. return MessageService\MessageStatus::DELIVERED;
  151. break;
  152. case 'accepted':
  153. return MessageService\MessageStatus::ACCEPTED;
  154. break;
  155. case 'enrouted':
  156. return MessageService\MessageStatus::SENT;
  157. break;
  158. case 'undeliverable':
  159. case 'expired':
  160. case 'deleted':
  161. return MessageService\MessageStatus::UNDELIVERED;
  162. break;
  163. case 'reject':
  164. case 'notsent':
  165. case 'textblacklist':
  166. case 'noviber':
  167. case 'blocked':
  168. case 'unknown':
  169. case 'nostatus':
  170. return MessageService\MessageStatus::FAILED;
  171. break;
  172. }
  173. return $status;
  174. }
  175. public function sync()
  176. {
  177. if ($this->isRegistered())
  178. {
  179. $this->loadFromList();
  180. }
  181. return $this;
  182. }
  183. private function loadFromList()
  184. {
  185. $result = $this->sendGetRequest('balance/packets');
  186. if ($result->isSuccess())
  187. {
  188. $from = [];
  189. $resultData = $result->getData();
  190. foreach ($resultData['packets'] as $packet)
  191. {
  192. if (isset($packet['targets']) && is_array($packet['targets']))
  193. {
  194. foreach ($packet['targets'] as $target)
  195. {
  196. $from[] = array(
  197. 'id' => $target,
  198. 'name' => $target
  199. );
  200. }
  201. }
  202. }
  203. $this->setOption('from_list', $from);
  204. }
  205. }
  206. private function makeSignature($text, $key = null)
  207. {
  208. if (!$key)
  209. {
  210. $key = $this->getOption('api_key');
  211. }
  212. return hash_hmac("sha256", $text, $key);
  213. }
  214. private function sendGetRequest($path, $signature = null, $login = null)
  215. {
  216. if (!$signature)
  217. {
  218. $signature = $this->makeSignature(str_replace('/', '', $path));
  219. }
  220. if (!$login)
  221. {
  222. $login = $this->getOption('login');
  223. }
  224. return $this->sendHttpRequest(HttpClient::HTTP_GET, $login, $signature, $path);
  225. }
  226. private function sendPostRequest($path, array $params)
  227. {
  228. $login = $this->getOption('login');
  229. $requestBody = Json::encode($params);
  230. $signature = $this->makeSignature(str_replace('/', '', $path).$requestBody);
  231. return $this->sendHttpRequest(HttpClient::HTTP_POST, $login, $signature, $path, $requestBody);
  232. }
  233. private function sendHttpRequest($method, $login, $signature, $path, $body = null): Sender\Result\HttpRequestResult
  234. {
  235. $httpClient = new HttpClient(array(
  236. "socketTimeout" => 10,
  237. "streamTimeout" => 30,
  238. "waitResponse" => true,
  239. ));
  240. $httpClient->setCharset('UTF-8');
  241. $httpClient->setHeader('User-Agent', 'Bitrix24');
  242. $httpClient->setHeader('Content-Type', 'application/json');
  243. $httpClient->setHeader('Authorization-User', $login);
  244. $httpClient->setHeader('Authorization', "Bearer $signature");
  245. $result = new Sender\Result\HttpRequestResult();
  246. $answer = ['error' => -1000];
  247. $url = self::JSON_API_URL.$path;
  248. $result->setHttpRequest(new MessageService\DTO\Request([
  249. 'method' => $method,
  250. 'uri' => $url,
  251. 'headers' => method_exists($httpClient, 'getRequestHeaders') ? $httpClient->getRequestHeaders()->toArray() : [],
  252. 'body' => $body,
  253. ]));
  254. if ($httpClient->query($method, $url, $body))
  255. {
  256. try
  257. {
  258. $answer = Json::decode($httpClient->getResult());
  259. }
  260. catch (\Bitrix\Main\ArgumentException $e)
  261. {
  262. }
  263. }
  264. if (isset($answer['error']))
  265. {
  266. $result->addError(new Error($this->getErrorMessage($answer['error']['code'], $answer['error']['message'])));
  267. }
  268. $result->setHttpResponse(new MessageService\DTO\Response([
  269. 'statusCode' => $httpClient->getStatus(),
  270. 'headers' => $httpClient->getHeaders()->toArray(),
  271. 'body' => $httpClient->getResult(),
  272. 'error' => Sender\Util::getHttpClientErrorString($httpClient)
  273. ]));
  274. $result->setData($answer);
  275. return $result;
  276. }
  277. private function getErrorMessage($errorCode, $text = null)
  278. {
  279. $message = Loc::getMessage('MESSAGESERVICE_SENDER_SMS_SMSLINE_ERROR_'.$errorCode, null, 'ru');
  280. return $message ?: ($text ?: Loc::getMessage('MESSAGESERVICE_SENDER_SMS_SMSLINE_ERROR_OTHER',null, 'ru'));
  281. }
  282. }