3namespace Bitrix\Main\Mail\Callback;
5use Bitrix\Mail\Helper\OAuth;
6use Bitrix\Main\ArgumentException;
7use Bitrix\Main\Context;
9use Bitrix\Main\LoaderException;
10use Bitrix\Main\Mail\Address;
11use Bitrix\Main\Mail\Smtp\CloudOAuthRefreshData;
12use Bitrix\Main\Mail\Smtp\OAuthConfigPreparer;
13use Bitrix\Main\SystemException;
14use Bitrix\Main\Web\Json;
15use Bitrix\Main\Mail\Internal;
16use Bitrix\Main\Mail\SenderSendCounter;
17use Bitrix\Main\Mail\Sender;
33 private const DESC_SMTP_LIMITED =
'SMTP_LIMITED';
77 $request = Context::getCurrent()->getRequest();
82 if (!isset($parameters[
'IGNORE_ITEM_ERRORS']))
84 $parameters[
'ENABLE_ITEM_ERRORS'] = mb_strtoupper(
$request->get(
'enableItemErrors')) ===
'Y';
88 if ($parameters[
'ENABLE_ITEM_ERRORS'])
97 self::giveAnswer(
true,
'No input data.');
108 if (!is_array(
$data))
110 self::giveAnswer(
true,
'Wrong data.');
113 if (!isset(
$data[
'list']) || !is_array(
$data[
'list']))
115 self::giveAnswer(
true,
'Parameter `list` required.');
120 self::giveAnswer(
false, [
'list' =>
$instance->getCounters()]);
127 'text' => self::$answerExceptions ? $exception->getMessage() :
null,
141 public static function giveAnswer($isError =
false, $answer =
null)
143 $response = Context::getCurrent()->getResponse();
144 $response->addHeader(
'Status', $isError ?
'422' :
'200');
145 $response->addHeader(
'Content-Type',
'application/json');
147 if (!is_array($answer))
150 'text' => $answer ?: null
153 $answer[
'error'] = $isError;
154 if (empty($answer[
'text']))
156 $answer[
'text'] = $isError ?
'Unknown error' :
'Success';
158 $answer = Json::encode($answer);
160 \CMain::FinalActions($answer);
169 $this->config =
new Config();
170 $this->result =
new Result();
171 $this->address =
new Address();
187 if (empty($item[
'id']))
191 if(!preg_match(
"/[a-zA-Z0-1=]{3,}/", $item[
'id']))
196 if (empty($item[
'sign']))
198 throw new ArgumentException(
"Field `sign` is required for item with id `{$item['id']}`.");
201 if (empty($item[
'status']))
203 throw new ArgumentException(
"Field `status` is required for item with id `{$item['id']}`.");
206 if (empty($item[
'email']))
208 throw new ArgumentException(
"Field `email` is required for item with id `{$item['id']}`.");
221 $this->countItems =
count($list);
223 $this->blacklist = [];
224 $this->smtpLimited = [];
225 foreach ($list as $index => $item)
227 $this->countItemsProcessed++;
233 $this->countItemsError++;
238 $this->countItemsError++;
258 if (!$this->smtpLimited)
263 foreach ($this->smtpLimited as
$email)
265 Sender::setEmailLimit(
284 $this->config->unpackId($item[
'id']);
285 if (!$this->config->verifySignature($item[
'sign']))
290 if (!$this->config->getEntityId())
295 $email = $this->address->set($item[
'email'])->getEmail();
301 $this->processAsRefreshRequest($item);
303 if (!empty($item[
'sender']) && self::isSmtpLimited($item[
'statusDescription']) )
305 $this->smtpLimited[] = $this->address->set($item[
'sender'])->getEmail();
309 ->setModuleId($this->config->getModuleId())
310 ->setEntityType($this->config->getEntityType())
311 ->setEntityId($this->config->getEntityId())
313 ->setDateSent((
int) $item[
'completedAt'])
314 ->setError(self::isStatusError($item[
'status']))
315 ->setPermanentError(self::isStatusPermanentError($item[
'status']))
316 ->setBlacklistable(self::isBlacklistable($item[
'statusDescription']))
317 ->setDescription($item[
'statusDescription'])
318 ->setMessage($item[
'message']);
320 if ($this->result->isPermanentError() && $this->result->isBlacklistable())
322 $this->blacklist[] = $this->result->getEmail();
325 $this->result->sendEvent();
338 'all' => $this->countItems,
339 'processed' => $this->countItemsProcessed,
340 'errors' => $this->countItemsError,
343 if ($this->refreshedTokens)
345 $result[
'refreshedTokens'] = $this->refreshedTokens;
359 return in_array(
$status, [self::STATUS_DEFERED, self::STATUS_BOUNCED]);
370 return $status === self::STATUS_BOUNCED;
390 private static function isSmtpLimited(
string $description)
399 private function processAsRefreshRequest(
array $item): void
401 if (empty($item[
'refreshUid']) || !isset($item[
'refreshExpires']) || empty($item[
'refreshSign']))
406 $uid = (string)base64_decode($item[
'refreshUid']);
407 $data =
new CloudOAuthRefreshData(
$uid, (
int)$item[
'refreshExpires']);
408 if (!
$data->isSignValid((
string)$item[
'refreshSign']))
415 throw new SystemException(
'Module mail not installed');
418 $mailOAuth = OAuth::getInstanceByMeta(
$uid);
419 if (!$mailOAuth || !$mailOAuth->getStoredUid())
421 throw new SystemException(
'Incorrect refresh meta');
424 $expireGapSeconds = (
new OAuthConfigPreparer())->getOAuthTokenExpireGapSeconds();
425 $token = $mailOAuth->getStoredToken(
null, $expireGapSeconds);
428 throw new SystemException(
'Cannot refresh token');
431 $expires = $defaultExpires = time() + $expireGapSeconds;
432 $oauthEntity = $mailOAuth->getOAuthEntity();
433 if (is_object($oauthEntity) && method_exists($oauthEntity,
'getTokenData'))
435 $expires = $oauthEntity->getTokenData()[
'expires_in'] ?? $defaultExpires;
438 $this->refreshedTokens[] = [
439 'uid' => $item[
'refreshUid'],
440 'accessToken' => $token,
441 'expires' => (int)$expires,
if(!Loader::includeModule('catalog')) if(!AccessController::getCurrent() ->check(ActionDictionary::ACTION_PRICE_EDIT)) if(!check_bitrix_sessid()) $request
static includeModule($moduleName)
static isStatusPermanentError($status)
static run($data=null, array $parameters=[])
static isBlacklistable($description)
static isStatusError($status)
static giveAnswer($isError=false, $answer=null)
static insertBatch(array $list)
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
if(Loader::includeModule( 'bitrix24')) elseif(Loader::includeModule('intranet') &&CIntranetUtils::getPortalZone() !=='ru') $description
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"