Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
smsru.php
1<?php
3
10
14
16
17Loc::loadMessages(__FILE__);
18
20{
21 use Sender\Traits\RussianProvider;
22
23 public const ID = 'smsru';
24
25 public function getId()
26 {
27 return static::ID;
28 }
29
30 public function getName()
31 {
32 return Loc::getMessage('MESSAGESERVICE_SENDER_SMS_SMSRU_NAME');
33 }
34
35 public function getShortName()
36 {
37 return 'sms.ru';
38 }
39
40 public function isDemo()
41 {
42 return false;
43 }
44
45 public function getDemoBalance()
46 {
47 $params = array(
48 'embed_id' => $this->getOption('embed_id')
49 );
50 $apiResult = $this->callExternalMethod('my/free', $params);
51
52 $balance = array(
53 'total_free' => 0,
54 'used_today' => 0,
55 'available_today' => 0
56 );
57
58 if ($apiResult->isSuccess())
59 {
60 $balanceData = $apiResult->getData();
61 $balance['total_free'] = (int)$balanceData['total_free'];
62 $balance['used_today'] = (int)$balanceData['used_today'];
63 $balance['available_today'] = max(0, $balance['total_free'] - $balance['used_today']);
64 }
65
66 return $balance;
67 }
68
69 public function getFromList()
70 {
71 $from = $this->getOption('from_list');
72 return is_array($from) ? $from : array();
73 }
74
75 public function isConfirmed()
76 {
77 return ($this->getOption('is_confirmed') === true);
78 }
79
80 public function isRegistered()
81 {
82 return ($this->getOption('embed_id') !== null);
83 }
84
85 public function register(array $fields)
86 {
87 $userPhone = \NormalizePhone($fields['user_phone']);
88 $params = array(
89 'user_phone' => $userPhone,
90 'user_firstname' => $fields['user_firstname'],
91 'user_lastname' => $fields['user_lastname'],
92 'user_email' => $fields['user_email'],
93 'embed_partner' => $this->getEmbedPartner(),
94 'embed_hash' => $this->getEmbedHash($userPhone)
95 );
96
97 $result = $this->callExternalMethod('embed/register', $params);
98 if ($result->isSuccess())
99 {
100 $data = $result->getData();
101
102 $this->setOption('embed_id', $data['embed_id']);
103 $this->setOption('user_phone', $userPhone);
104 if (!empty($params['user_firstname']))
105 {
106 $this->setOption('user_firstname', $params['user_firstname']);
107 }
108 if (!empty($params['user_lastname']))
109 {
110 $this->setOption('user_lastname', $params['user_lastname']);
111 }
112 if (!empty($params['user_email']))
113 {
114 $this->setOption('user_email', $params['user_email']);
115 }
116
117 if (!empty($data['confirmed']))
118 {
119 $this->setOption('is_confirmed', true);
120 }
121 }
122
123 return $result;
124 }
125
134 public function getOwnerInfo()
135 {
136 return array(
137 'phone' => $this->getOption('user_phone'),
138 'firstName' => $this->getOption('user_firstname'),
139 'lastName' => $this->getOption('user_lastname'),
140 'email' => $this->getOption('user_email')
141 );
142 }
143
148 public function confirmRegistration(array $fields)
149 {
150 $embedId = $this->getOption('embed_id');
151 $params = array(
152 'embed_id' => $embedId,
153 'confirm' => $fields['confirm']
154 );
155 $result = $this->callExternalMethod('embed/confirm', $params);
156
157 if ($result->isSuccess())
158 {
159 $this->setOption('is_confirmed', true);
160 $callBackResult = $this->callExternalMethod('callback/add', array(
161 'embed_id' => $embedId,
162 'url' => $this->getCallbackUrl()
163 ));
164 if ($callBackResult->isSuccess())
165 {
166 $this->setOption('callback_set', true);
167 }
168 }
169
170 return $result;
171 }
172
173 public function sendConfirmationCode()
174 {
175 if ($this->isRegistered())
176 {
177 $ownerInfo = $this->getOwnerInfo();
178 $result = $this->register(array(
179 'user_phone' => $ownerInfo['phone'],
180 'user_firstname' => $ownerInfo['firstName'],
181 'user_lastname' => $ownerInfo['lastName'],
182 'user_email' => $ownerInfo['email'],
183 ));
184 }
185 else
186 {
187 $result = new Result();
188 $result->addError(new Error('Provider is not registered.'));
189 }
190
191 return $result;
192 }
193
194 public function getExternalManageUrl()
195 {
196 if ($this->isRegistered())
197 {
198 return 'https://sms.ru/?panel=login&action=login&embed_id='.$this->getOption('embed_id');
199 }
200 return 'https://sms.ru/?panel=login';
201 }
202
203 public function sendMessage(array $messageFields)
204 {
205 if (!$this->canUse())
206 {
207 $result = new SendMessage();
208 $result->addError(new Error(Loc::getMessage('MESSAGESERVICE_SENDER_SMS_SMSRU_CAN_USE_ERROR')));
209 return $result;
210 }
211
212 $params = array(
213 'to' => $messageFields['MESSAGE_TO'],
214 'text' => $this->prepareMessageBodyForSend($messageFields['MESSAGE_BODY']),
215 'embed_id' => $this->getOption('embed_id')
216 );
217
218 if ($this->isDemo())
219 {
220 $params['to'] = $this->getOption('user_phone');
221 }
222
223 if ($messageFields['MESSAGE_FROM'])
224 {
225 $params['from'] = $messageFields['MESSAGE_FROM'];
226 }
227
228 $result = new SendMessage();
229 $apiResult = $this->callExternalMethod('sms/send', $params);
230 $result->setServiceRequest($apiResult->getHttpRequest());
231 $result->setServiceResponse($apiResult->getHttpResponse());
232
233 $resultData = $apiResult->getData();
234
235 if (!$apiResult->isSuccess())
236 {
237 if ((int)$resultData['status_code'] == 206)
238 {
239 $result->setStatus(MessageService\MessageStatus::DEFERRED);
240 $result->addError(new Error($this->getErrorMessage($resultData['status_code'])));
241 }
242 else
243 {
244 $result->addErrors($apiResult->getErrors());
245 }
246 }
247 else
248 {
249 $smsData = current($resultData['sms']);
250
251 if (isset($smsData['sms_id']))
252 {
253 $result->setExternalId($smsData['sms_id']);
254 }
255
256 if ((int)$smsData['status_code'] !== 100)
257 {
258 $result->addError(new Error($this->getErrorMessage($smsData['status_code'])));
259 }
260 elseif ((int)$smsData['status_code'] == 206)
261 {
262 $result->setStatus(MessageService\MessageStatus::DEFERRED);
263 $result->addError(new Error($this->getErrorMessage($smsData['status_code'])));
264 }
265 else
266 {
267 $result->setAccepted();
268 }
269 }
270
271 return $result;
272 }
273
274 public function getMessageStatus(array $messageFields)
275 {
276 $result = new MessageStatus();
277 $result->setId($messageFields['ID']);
278 $result->setExternalId($messageFields['EXTERNAL_ID']);
279
280 if (!$this->canUse())
281 {
282 $result->addError(new Error(Loc::getMessage('MESSAGESERVICE_SENDER_SMS_SMSRU_CAN_USE_ERROR')));
283 return $result;
284 }
285
286 $params = array(
287 'sms_id' => $result->getExternalId(),
288 'embed_id' => $this->getOption('embed_id')
289 );
290
291 $apiResult = $this->callExternalMethod('sms/status', $params);
292 if (!$apiResult->isSuccess())
293 {
294 $result->addErrors($apiResult->getErrors());
295 }
296 else
297 {
298 $resultData = $apiResult->getData();
299 $smsData = current($resultData['sms']);
300
301 $result->setStatusCode($smsData['status_code']);
302 $result->setStatusText($smsData['status_text']);
303
304 if ((int)$resultData['status_code'] !== 100)
305 {
306 $result->addError(new Error($this->getErrorMessage($smsData['status_code'])));
307 }
308 }
309
310 return $result;
311 }
312
313 public static function resolveStatus($serviceStatus)
314 {
315 $status = parent::resolveStatus($serviceStatus);
316
317 switch ((int)$serviceStatus)
318 {
319 case 100:
320 return MessageService\MessageStatus::ACCEPTED;
321 break;
322 case 101:
323 return MessageService\MessageStatus::SENDING;
324 break;
325 case 102:
326 return MessageService\MessageStatus::SENT;
327 break;
328 case 103:
329 return MessageService\MessageStatus::DELIVERED;
330 break;
331 case 104: //timeout
332 case 105: //removed by moderator
333 case 106: //error on receiver`s side
334 case 107: //unknown reason
335 case 108: //rejected
336 return MessageService\MessageStatus::UNDELIVERED;
337 break;
338 case 110:
339 return MessageService\MessageStatus::READ;
340 break;
341 }
342
343 return $status;
344 }
345
346 public function sync()
347 {
348 if ($this->isRegistered())
349 {
350 $this->loadFromList();
351 }
352 return $this;
353 }
354
355 private function callExternalMethod($method, $params): Sender\Result\HttpRequestResult
356 {
357 $url = 'https://sms.ru/'.$method;
358
359 $httpClient = new HttpClient(array(
360 "socketTimeout" => $this->socketTimeout,
361 "streamTimeout" => $this->streamTimeout,
362 "waitResponse" => true,
363 ));
364 $httpClient->setHeader('User-Agent', 'Bitrix24');
365 $httpClient->setCharset('UTF-8');
366
367 $isUtf = Application::getInstance()->isUtfMode();
368
369 if (!$isUtf)
370 {
371 $params = \Bitrix\Main\Text\Encoding::convertEncoding($params, SITE_CHARSET, 'UTF-8');
372 }
373 $params['json'] = 1;
374
375 $result = new Sender\Result\HttpRequestResult();
376 $answer = array();
377
378 $result->setHttpRequest(new MessageService\DTO\Request([
379 'method' => HttpClient::HTTP_POST,
380 'uri' => $url,
381 'headers' => method_exists($httpClient, 'getRequestHeaders') ? $httpClient->getRequestHeaders()->toArray() : [],
382 'body' => $params,
383 ]));
384 if ($httpClient->query(HttpClient::HTTP_POST, $url, $params) && $httpClient->getStatus() == '200')
385 {
386 $answer = $this->parseExternalAnswer($httpClient->getResult());
387 }
388
389 $answerCode = isset($answer['status_code']) ? (int)$answer['status_code'] : 0;
390
391 if ($answerCode !== 100)
392 {
393 $result->addError(new Error($this->getErrorMessage($answerCode, $answer)));
394 }
395 $result->setData($answer);
396 $result->setHttpResponse(new MessageService\DTO\Response([
397 'statusCode' => $httpClient->getStatus(),
398 'headers' => $httpClient->getHeaders()->toArray(),
399 'body' => $httpClient->getResult(),
400 'error' => Sender\Util::getHttpClientErrorString($httpClient)
401 ]));
402
403 return $result;
404 }
405
406 private function parseExternalAnswer($httpResult)
407 {
408 try
409 {
410 $answer = Json::decode($httpResult);
411 }
412 catch (\Bitrix\Main\ArgumentException $e)
413 {
414 $data = explode(PHP_EOL, $httpResult);
415 $code = (int)array_shift($data);
416 $answer = $data;
417 $answer['status_code'] = $code;
418 $answer['status'] = $code === 100 ? 'OK' : 'ERROR';
419 }
420
421 if (!is_array($answer) && is_numeric($answer))
422 {
423 $answer = array(
424 'status' => $answer === 100 ? 'OK' : 'ERROR',
425 'status_code' => $answer
426 );
427 }
428
429 return $answer;
430 }
431
432 private function getEmbedPartner()
433 {
434 return 'bitrix24';//Option::get('messageservice', 'smsru_partner');
435 }
436
437 private function getSecretKey()
438 {
439 return 'P46y811M84W3b4H18SmDpy9KG3pKG3Ok';//Option::get('messageservice', 'smsru_secret_key');
440 }
441
442 private function getEmbedHash($phoneNumber)
443 {
444 return md5($phoneNumber.$this->getSecretKey());
445 }
446
447 private function getErrorMessage($errorCode, $answer = null)
448 {
449 $message = Loc::getMessage('MESSAGESERVICE_SENDER_SMS_SMSRU_ERROR_'.$errorCode);
450 if (!$message && $answer && !empty($answer['errors']))
451 {
452 $errorCode = $answer['errors'][0]['status_code'];
453 $message = Loc::getMessage('MESSAGESERVICE_SENDER_SMS_SMSRU_ERROR_'.$errorCode);
454 if (!$message)
455 {
456 $message = $answer['errors'][0]['status_text'];
457 }
458 }
459
460 return $message ?: Loc::getMessage('MESSAGESERVICE_SENDER_SMS_SMSRU_ERROR_OTHER');
461 }
462
463 private function loadFromList()
464 {
465 $params = array(
466 'embed_id' => $this->getOption('embed_id')
467 );
468 $result = $this->callExternalMethod('my/senders', $params);
469
470 if ($result->isSuccess())
471 {
472 $from = array();
473 $resultData = $result->getData();
474 foreach ($resultData['senders'] as $sender)
475 {
476 if (!empty($sender))
477 {
478 $from[] = array(
479 'id' => $sender,
480 'name' => $sender
481 );
482 }
483 }
484
485 $this->setOption('from_list', $from);
486 }
487 }
488}
static loadMessages($file)
Definition loc.php:64
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
getOption($optionName, $defaultValue=null)
prepareMessageBodyForSend(string $text)
Definition base.php:176
Providers Sender $sender
Definition base.php:13
sendMessage(array $messageFields)
Definition smsru.php:203
static resolveStatus($serviceStatus)
Definition smsru.php:313
getMessageStatus(array $messageFields)
Definition smsru.php:274
static getHttpClientErrorString(HttpClient $httpClient)
Definition util.php:24