21
21
use Bitrix24 \Exceptions \Bitrix24PaymentRequiredException ;
22
22
use Bitrix24 \Exceptions \Bitrix24PortalDeletedException ;
23
23
use Bitrix24 \Exceptions \Bitrix24PortalRenamedException ;
24
+ use Bitrix24 \Exceptions \Bitrix24RestApiUnavailableOnFreeTariffException ;
24
25
use Bitrix24 \Exceptions \Bitrix24SecurityException ;
25
26
use Bitrix24 \Exceptions \Bitrix24TokenIsExpiredException ;
26
27
use Bitrix24 \Exceptions \Bitrix24TokenIsInvalidException ;
@@ -143,11 +144,25 @@ class Bitrix24 implements iBitrix24
143
144
*/
144
145
protected $ _onExpiredToken ;
145
146
147
+ /**
148
+ * @var callable callback after api method called
149
+ */
150
+ protected $ _onCallApiMethod ;
151
+
146
152
/**
147
153
* @var bool ssl verify for checking CURLOPT_SSL_VERIFYPEER and CURLOPT_SSL_VERIFYHOST
148
154
*/
149
155
protected $ sslVerify = true ;
150
156
157
+ /**
158
+ * @var bool if true - webhook will be used in API calls (without access_token)
159
+ */
160
+ protected $ webhook_usage ;
161
+
162
+ /**
163
+ * @var string webhook secret identifier
164
+ */
165
+ protected $ webhook_secret ;
151
166
152
167
/**
153
168
* Create a object to work with Bitrix24 REST API service
@@ -195,6 +210,16 @@ public function setOnExpiredToken(callable $callback)
195
210
$ this ->_onExpiredToken = $ callback ;
196
211
}
197
212
213
+ /**
214
+ * Set function called after api method executed. Callback receives instance as first parameter, method name as second.
215
+ *
216
+ * @param callable $callback
217
+ */
218
+ public function setOnCallApiMethod (callable $ callback )
219
+ {
220
+ $ this ->_onCallApiMethod = $ callback ;
221
+ }
222
+
198
223
/**
199
224
* Get a random string to sign protected api-call. Use salt for argument "state" in secure api-call
200
225
* random string is a result of mt_rand function
@@ -504,14 +529,14 @@ protected function executeRequest($url, array $additionalParameters = array())
504
529
$ curlOptions = array (
505
530
CURLOPT_FOLLOWLOCATION => true ,
506
531
CURLOPT_RETURNTRANSFER => true ,
507
- CURLINFO_HEADER_OUT => true ,
508
- CURLOPT_VERBOSE => true ,
532
+ CURLINFO_HEADER_OUT => true ,
533
+ CURLOPT_VERBOSE => true ,
509
534
CURLOPT_CONNECTTIMEOUT => 65 ,
510
- CURLOPT_TIMEOUT => 70 ,
511
- CURLOPT_USERAGENT => strtolower (__CLASS__ . '-PHP-SDK/v ' . self ::VERSION ),
512
- CURLOPT_POST => true ,
513
- CURLOPT_POSTFIELDS => http_build_query ($ additionalParameters ),
514
- CURLOPT_URL => $ url ,
535
+ CURLOPT_TIMEOUT => 70 ,
536
+ CURLOPT_USERAGENT => strtolower (__CLASS__ . '-PHP-SDK/v ' . self ::VERSION ),
537
+ CURLOPT_POST => true ,
538
+ CURLOPT_POSTFIELDS => http_build_query ($ additionalParameters ),
539
+ CURLOPT_URL => $ url ,
515
540
);
516
541
517
542
if (!$ this ->sslVerify ) {
@@ -537,8 +562,12 @@ protected function executeRequest($url, array $additionalParameters = array())
537
562
// handling network I/O errors
538
563
if (false === $ curlResult ) {
539
564
$ curlErrorNumber = curl_errno ($ curl );
540
- $ errorMsg = sprintf ('in try[%s] cURL error (code %s): %s ' . PHP_EOL , $ retriesCnt , $ curlErrorNumber ,
541
- curl_error ($ curl ));
565
+ $ errorMsg = sprintf (
566
+ 'in try[%s] cURL error (code %s): %s ' . PHP_EOL ,
567
+ $ retriesCnt ,
568
+ $ curlErrorNumber ,
569
+ curl_error ($ curl )
570
+ );
542
571
if (false === in_array ($ curlErrorNumber , $ retryableErrorCodes , true ) || !$ retriesCnt ) {
543
572
$ this ->log ->error ($ errorMsg , $ this ->getErrorContext ());
544
573
curl_close ($ curl );
@@ -603,19 +632,19 @@ protected function getErrorContext()
603
632
{
604
633
return array (
605
634
// portal specific settings
606
- 'B24_DOMAIN ' => $ this ->getDomain (),
607
- 'B24_MEMBER_ID ' => $ this ->getMemberId (),
608
- 'B24_ACCESS_TOKEN ' => $ this ->getAccessToken (),
609
- 'B24_REFRESH_TOKEN ' => $ this ->getRefreshToken (),
635
+ 'B24_DOMAIN ' => $ this ->getDomain (),
636
+ 'B24_MEMBER_ID ' => $ this ->getMemberId (),
637
+ 'B24_ACCESS_TOKEN ' => $ this ->getAccessToken (),
638
+ 'B24_REFRESH_TOKEN ' => $ this ->getRefreshToken (),
610
639
// application settings
611
- 'APPLICATION_SCOPE ' => $ this ->getApplicationScope (),
612
- 'APPLICATION_ID ' => $ this ->getApplicationId (),
640
+ 'APPLICATION_SCOPE ' => $ this ->getApplicationScope (),
641
+ 'APPLICATION_ID ' => $ this ->getApplicationId (),
613
642
'APPLICATION_SECRET ' => $ this ->getApplicationSecret (),
614
- 'REDIRECT_URI ' => $ this ->getRedirectUri (),
643
+ 'REDIRECT_URI ' => $ this ->getRedirectUri (),
615
644
// network
616
- 'RAW_REQUEST ' => $ this ->getRawRequest (),
617
- 'CURL_REQUEST_INFO ' => $ this ->getRequestInfo (),
618
- 'RAW_RESPONSE ' => $ this ->getRawResponse (),
645
+ 'RAW_REQUEST ' => $ this ->getRawRequest (),
646
+ 'CURL_REQUEST_INFO ' => $ this ->getRequestInfo (),
647
+ 'RAW_RESPONSE ' => $ this ->getRawResponse (),
619
648
);
620
649
}
621
650
@@ -762,14 +791,15 @@ protected function handleBitrix24APILevelErrors(
762
791
$ arRequestResult ,
763
792
$ methodName ,
764
793
array $ additionalParameters = array ()
765
- )
766
- {
794
+ ) {
767
795
if (array_key_exists ('error ' , $ arRequestResult )) {
768
- $ errorMsg = sprintf ('%s - %s in call [%s] for domain [%s] ' ,
796
+ $ errorMsg = sprintf (
797
+ '%s - %s in call [%s] for domain [%s] ' ,
769
798
$ arRequestResult ['error ' ],
770
799
(array_key_exists ('error_description ' , $ arRequestResult ) ? $ arRequestResult ['error_description ' ] : '' ),
771
800
$ methodName ,
772
- $ this ->getDomain ());
801
+ $ this ->getDomain ()
802
+ );
773
803
// throw specific API-level exceptions
774
804
switch (strtoupper (trim ($ arRequestResult ['error ' ]))) {
775
805
case 'WRONG_CLIENT ' :
@@ -795,6 +825,9 @@ protected function handleBitrix24APILevelErrors(
795
825
case 'INSUFFICIENT_SCOPE ' :
796
826
$ this ->log ->error ($ errorMsg , $ this ->getErrorContext ());
797
827
throw new Bitrix24InsufficientScope ($ errorMsg );
828
+ case 'ACCESS_DENIED ' :
829
+ $ this ->log ->error ($ errorMsg , $ this ->getErrorContext ());
830
+ throw new Bitrix24RestApiUnavailableOnFreeTariffException ($ errorMsg );
798
831
default :
799
832
$ this ->log ->error ($ errorMsg , $ this ->getErrorContext ());
800
833
throw new Bitrix24ApiException ($ errorMsg );
@@ -1016,9 +1049,9 @@ public function addBatchCall($method, array $parameters = array(), callable $cal
1016
1049
{
1017
1050
$ id = uniqid ();
1018
1051
$ this ->_batch [$ id ] = array (
1019
- 'method ' => $ method ,
1052
+ 'method ' => $ method ,
1020
1053
'parameters ' => $ parameters ,
1021
- 'callback ' => $ callback ,
1054
+ 'callback ' => $ callback ,
1022
1055
);
1023
1056
1024
1057
return $ id ;
@@ -1070,9 +1103,9 @@ public function processBatchCalls($halt = 0, $delay = self::BATCH_DELAY)
1070
1103
1071
1104
call_user_func ($ call ['callback ' ], array (
1072
1105
'result ' => isset ($ results ['result ' ][$ idx ]) ? $ results ['result ' ][$ idx ] : null ,
1073
- 'error ' => isset ($ results ['result_error ' ][$ idx ]) ? $ results ['result_error ' ][$ idx ] : null ,
1074
- 'total ' => isset ($ results ['result_total ' ][$ idx ]) ? $ results ['result_total ' ][$ idx ] : null ,
1075
- 'next ' => isset ($ results ['result_next ' ][$ idx ]) ? $ results ['result_next ' ][$ idx ] : null ,
1106
+ 'error ' => isset ($ results ['result_error ' ][$ idx ]) ? $ results ['result_error ' ][$ idx ] : null ,
1107
+ 'total ' => isset ($ results ['result_total ' ][$ idx ]) ? $ results ['result_total ' ][$ idx ] : null ,
1108
+ 'next ' => isset ($ results ['result_next ' ][$ idx ]) ? $ results ['result_next ' ][$ idx ] : null ,
1076
1109
));
1077
1110
}
1078
1111
if (count ($ this ->_batch ) && $ delay ) {
@@ -1105,7 +1138,12 @@ public function processBatchCalls($halt = 0, $delay = self::BATCH_DELAY)
1105
1138
public function call ($ methodName , array $ additionalParameters = array ())
1106
1139
{
1107
1140
try {
1108
- $ result = $ this ->_call ($ methodName , $ additionalParameters );
1141
+ $ result = $ this ->getWebhookUsage () ? $ this ->_call_webhook ($ methodName , $ additionalParameters )
1142
+ : $ this ->_call ($ methodName , $ additionalParameters );
1143
+
1144
+ if (is_callable ($ this ->_onCallApiMethod )) {
1145
+ call_user_func ($ this ->_onCallApiMethod , $ this , $ methodName );
1146
+ }
1109
1147
} catch (Bitrix24TokenIsExpiredException $ e ) {
1110
1148
if (!is_callable ($ this ->_onExpiredToken )) {
1111
1149
throw $ e ;
@@ -1115,7 +1153,9 @@ public function call($methodName, array $additionalParameters = array())
1115
1153
if (!$ retry ) {
1116
1154
throw $ e ;
1117
1155
}
1118
- $ result = $ this ->_call ($ methodName , $ additionalParameters );
1156
+
1157
+ $ result = $ this ->getWebhookUsage () ? $ this ->_call_webhook ($ methodName , $ additionalParameters )
1158
+ : $ this ->_call ($ methodName , $ additionalParameters );
1119
1159
}
1120
1160
1121
1161
return $ result ;
@@ -1166,8 +1206,8 @@ protected function _call($methodName, array $additionalParameters = array())
1166
1206
1167
1207
// execute request
1168
1208
$ this ->log ->info ('call bitrix24 method ' , array (
1169
- 'BITRIX24_DOMAIN ' => $ this ->domain ,
1170
- 'METHOD_NAME ' => $ methodName ,
1209
+ 'BITRIX24_DOMAIN ' => $ this ->domain ,
1210
+ 'METHOD_NAME ' => $ methodName ,
1171
1211
'METHOD_PARAMETERS ' => $ additionalParameters ,
1172
1212
));
1173
1213
$ requestResult = $ this ->executeRequest ($ url , $ additionalParameters );
@@ -1219,4 +1259,107 @@ protected function _call($methodName, array $additionalParameters = array())
1219
1259
1220
1260
return $ requestResult ;
1221
1261
}
1262
+
1263
+ /**
1264
+ * Set whether we using webhook or application in API calls
1265
+ * If true - use webhook in API call
1266
+ *
1267
+ * @param bool $webhook_usage_boolean
1268
+ *
1269
+ * @return bool
1270
+ */
1271
+ public function setWebhookUsage ($ webhook_usage_boolean )
1272
+ {
1273
+ $ this ->webhook_usage = $ webhook_usage_boolean ;
1274
+
1275
+ return true ;
1276
+ }
1277
+
1278
+ /**
1279
+ * Return whether we using webhook or application in API calls
1280
+ *
1281
+ * @return bool
1282
+ */
1283
+ public function getWebhookUsage ()
1284
+ {
1285
+ return $ this ->webhook_usage ;
1286
+ }
1287
+
1288
+ /**
1289
+ * Set webhook secret to use in API calls
1290
+ *
1291
+ * @param string $webhook_secret
1292
+ *
1293
+ * @return bool
1294
+ */
1295
+ public function setWebhookSecret ($ webhook_secret )
1296
+ {
1297
+ $ this ->webhook_secret = $ webhook_secret ;
1298
+
1299
+ return true ;
1300
+ }
1301
+
1302
+ /**
1303
+ * Return string with webhook secret
1304
+ *
1305
+ * @return string
1306
+ */
1307
+ public function getWebhookSecret ()
1308
+ {
1309
+ return $ this ->webhook_secret ;
1310
+ }
1311
+
1312
+ /**
1313
+ * Execute Bitrix24 REST API method using webhook
1314
+ *
1315
+ * @param string $methodName
1316
+ * @param array $additionalParameters
1317
+ *
1318
+ * @return array
1319
+ * @throws Bitrix24Exception
1320
+ * @throws Bitrix24ApiException
1321
+ * @throws Bitrix24TokenIsInvalidException
1322
+ * @throws Bitrix24TokenIsExpiredException
1323
+ * @throws Bitrix24WrongClientException
1324
+ * @throws Bitrix24MethodNotFoundException
1325
+ * @throws Bitrix24PaymentRequiredException
1326
+ * @throws Bitrix24SecurityException
1327
+ * @throws Bitrix24PortalDeletedException
1328
+ * @throws Bitrix24IoException
1329
+ * @throws Bitrix24EmptyResponseException
1330
+ * @throws Bitrix24PortalRenamedException
1331
+ */
1332
+ protected function _call_webhook ($ methodName , array $ additionalParameters = array ())
1333
+ {
1334
+ if (null === $ this ->getDomain ()) {
1335
+ throw new Bitrix24Exception ('domain not found, you must call setDomain method before ' );
1336
+ }
1337
+
1338
+ if ('' === $ methodName ) {
1339
+ throw new Bitrix24Exception ('method name not found, you must set method name ' );
1340
+ }
1341
+
1342
+ if (null === $ this ->getWebhookSecret ()) {
1343
+ throw new Bitrix24Exception ('no webhook secret provided, you must call setWebhookSecret method before ' );
1344
+ }
1345
+
1346
+ $ url = 'https:// ' . $ this ->domain . '/rest/ ' . $ this ->getWebhookSecret () . '/ ' . $ methodName ;
1347
+
1348
+ // save method parameters for debug
1349
+ $ this ->methodParameters = $ additionalParameters ;
1350
+
1351
+ // execute request
1352
+ $ this ->log ->info ('call bitrix24 method ' , array (
1353
+ 'BITRIX24_WEBHOOK_URL ' => $ url ,
1354
+ 'BITRIX24_DOMAIN ' => $ this ->domain ,
1355
+ 'METHOD_NAME ' => $ methodName ,
1356
+ 'METHOD_PARAMETERS ' => $ additionalParameters ,
1357
+ ));
1358
+ $ requestResult = $ this ->executeRequest ($ url , $ additionalParameters );
1359
+
1360
+ // check errors and throw exception if errors exists
1361
+ $ this ->handleBitrix24APILevelErrors ($ requestResult , $ methodName , $ additionalParameters );
1362
+
1363
+ return $ requestResult ;
1364
+ }
1222
1365
}
0 commit comments