1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
formvkontakte.php
См. документацию.
1<?php
2
3namespace Bitrix\Seo\LeadAds\Services;
4
5use Bitrix\Main\ArgumentNullException;
6use Bitrix\Main\Context;
7use Bitrix\Main\Error;
8use Bitrix\Main\Result;
9use Bitrix\Main\Security\Random;
10use Bitrix\Main\SystemException;
11use Bitrix\Main\Text\Encoding;
12use Bitrix\Main\Web\Json;
13use Bitrix\Seo\LeadAds;
14use Bitrix\Seo\Retargeting;
15use Bitrix\Seo\Retargeting\Response;
16use Bitrix\Seo\Service;
17use Bitrix\Seo\WebHook;
18use Bitrix\Seo\LeadAds\Response\FormResponse;
19use Bitrix\Seo\LeadAds\Response\Builder\VkontakteFormBuilder;
20
21
28{
30
31 public const LIMIT_DEFAULT = 20;
32 public const LIMIT_MAX = 50;
33 protected const STATUS_FORM_ACTIVE = 1;
34
35 public const URL_FORM_LIST = 'https://www.facebook.com/ads/manager/audiences/manage/';
36
37 public const USE_GROUP_AUTH = true;
38 public const FIELD_MAP = [
39 ['CRM_NAME' => LeadAds\Field::TYPE_NAME, 'ADS_NAME' => 'first_name'],
40 ['CRM_NAME' => LeadAds\Field::TYPE_LAST_NAME, 'ADS_NAME' => 'last_name'],
41 ['CRM_NAME' => LeadAds\Field::TYPE_EMAIL, 'ADS_NAME' => 'email'],
42 ['CRM_NAME' => LeadAds\Field::TYPE_PHONE, 'ADS_NAME' => 'phone'],
43 ['CRM_NAME' => LeadAds\Field::TYPE_BIRTHDAY, 'ADS_NAME'=>'birth_date'],
44 ['CRM_NAME' => LeadAds\Field::TYPE_AGE, 'ADS_NAME'=>'age'],
45 ['CRM_NAME' => LeadAds\Field::TYPE_LOCATION_FULL, 'ADS_NAME'=>'location'],
46 ['CRM_NAME' => LeadAds\Field::TYPE_PATRONYMIC_NAME, 'ADS_NAME'=>'patronymic_name'],
47 ['CRM_NAME' => LeadAds\Field::TYPE_LOCATION_COUNTRY, 'ADS_NAME'=>'country'],
48 ['CRM_NAME' => LeadAds\Field::TYPE_LOCATION_CITY, 'ADS_NAME'=>'city'],
49 ['CRM_NAME' => LeadAds\Field::TYPE_LOCATION_STREET_ADDRESS, 'ADS_NAME'=>'address'],
50 ['CRM_NAME' => LeadAds\Field::TYPE_INPUT, 'ADS_NAME'=>'question'],
51 ];
52
53 protected static $fieldKeyPrefix = 'b24-seo-ads-';
54
55 protected static $listRowMap = array(
56 'ID' => 'ID',
57 'NAME' => 'NAME',
58 'LOCALE' => 'LOCALE',
59 );
60
61 protected function getAuthParameters() : array
62 {
63 $row = LeadAds\Internals\CallbackSubscriptionTable::getRow([
64 'filter' => [
65 '=TYPE' => static::TYPE_CODE,
66 ]
67 ]);
68
69 return [
70 'URL_PARAMETERS' => ['group_ids' => $row['GROUP_ID']]
71 ];
72 }
73
80 public static function convertField(LeadAds\Field $field) : array
81 {
82 $mapper = static::getFieldMapper();
83 $adsName = $mapper->getAdsName($field->getName());
84 if ($adsName)
85 {
86 return [
87 'type' => $adsName,
88 //'key' => $field->getKey()
89 ];
90 }
91
92 $item = [
93 'type' => $field->getType(),
94 'key' => $field->getKey(),
95 'label' => $field->getLabel(),
96 ];
97
98 if (!empty($field->getOptions()))
99 {
100 $item['options'] = array_map(
101 static function ($option)
102 {
103 if (is_numeric($key = $option['key']))
104 {
105 $key = static::$fieldKeyPrefix . $key;
106 }
107
108 return [
109 'label' => $option['label'],
110 'key' => $key
111 ];
112 },
113 $field->getOptions()
114 );
115 }
116
117 return $item;
118 }
119
127 public function add(array $data) : Response
128 {
130 }
131
136 public function getForm($formId) : LeadAds\Response\FormResponse
137 {
139 $response = $this->getRequest()->send([
140 'methodName'=>'leadads.form.get',
141 'parameters'=>[
142 'form_id'=> (int) $formId,
143 'group_id'=> (int) $this->accountId,
144 ]
145 ]);
146
147 return new FormResponse(
148 new VkontakteFormBuilder($this::getFieldMapper()),
150 );
151 }
152
160 public function unlink(string $id) : bool
161 {
162 return $this->removeFormWebHook($this->accountId);
163 }
164
165 protected function registerGroupWebHook(): Retargeting\Services\ResponseVkontakte
166 {
168
169 $confirmationCodeResponse = $this->getCallbackConfirmationCode();
170 if ($confirmationCodeResponse instanceof Error)
171 {
172 $response->addError(
173 $confirmationCodeResponse
174 );
175
176 return $response;
177 }
178
179 $isRegistered = $this->registerFormWebHook(
180 $this->accountId,
181 array(
182 'SECURITY_CODE' => $secretKey = Random::getString(32),
183 'CONFIRMATION_CODE' => $confirmationCodeResponse,
184 )
185 );
186
187 if (!$isRegistered)
188 {
189 $response->addError(new Error('Can not register Form web hook.'));
190
191 return $response;
192 }
193
194 $callbackServiceResponse = $this->addCallbackServer($secretKey);
195 if ($callbackServiceResponse instanceof Error)
196 {
197 $response->addError($callbackServiceResponse);
198 }
199
200 return $response;
201 }
202
208 protected function addCallbackServer(string $secretKey)
209 {
210
211 $row = LeadAds\Internals\CallbackSubscriptionTable::getRow(
212 array(
213 'select' => ['ID','CALLBACK_SERVER_ID'],
214 'filter' => [
215 '=TYPE' => static::TYPE_CODE,
216 '=GROUP_ID' => $this->accountId
217 ]
218 )
219 );
220
221 if (!$row)
222 {
223 return new Error("Group is not registred.");
224 }
225
226 if (!empty($row['CALLBACK_SERVER_ID']))
227 {
228 return $row['CALLBACK_SERVER_ID'];
229 }
230
231 $responseSetCallbackSettings = $this->getRequest()->send([
232 'methodName' => 'leadads.callback.server.settings.set',
233 'parameters' => [
234 'group_id' => $this->accountId,
235 'lead_forms_new' => 1,
236 ]
237 ]);
238
239 if (!$responseSetCallbackSettings->isSuccess() || 1 !== current($responseSetCallbackSettings->getData()))
240 {
241 return new Error('Can not set Callback server settings.');
242 }
243
244 return true;
245 }
246
247 protected function deleteCallbackServer($groupId): void
248 {
249 $row = LeadAds\Internals\CallbackSubscriptionTable::getRow([
250 'filter' => [
251 '=TYPE' => static::TYPE_CODE,
252 '=GROUP_ID' => $groupId
253 ]
254 ]);
255
256 if ($row && !empty($row['CALLBACK_SERVER_ID']))
257 {
258 $this->getRequest()->send([
259 'methodName' => 'leadads.callback.server.delete',
260 'parameters' => [
261 'group_id' => $groupId,
262 'server_id' => $row['CALLBACK_SERVER_ID'],
263 ]
264 ]);
265 }
266 }
267
272 protected function getCallbackConfirmationCode()
273 {
274 $response = $this->getRequest()->send([
275 'methodName' => 'leadads.callback.server.code.get',
276 'parameters' => [
277 'group_id' => $this->accountId,
278 ]
279 ]);
280
281 if (!$response->isSuccess())
282 {
283 return new Error('Can not get confirmation code for Callback server.');
284 }
285
286 $responseData = $response->getData();
287
288 return empty($responseData['code'])
289 ? new Error('Can not get confirmation code for Callback server.')
290 : $responseData['code']
291 ;
292 }
293
300 public function getList() : FormResponse
301 {
302 $limit = self::LIMIT_DEFAULT;
303 $offset = 0;
304 $result = [];
306 while (true)
307 {
308 $response = $this->getRequest()->send([
309 'methodName' => 'leadads.form.list',
310 'parameters' => [
311 'limit' => $limit,
312 'offset' => $offset,
313 ]
314 ]);
315 $items = array_filter($response->getData(), fn ($item) => ((int)$item['status'] === self::STATUS_FORM_ACTIVE));
316 $result = array_merge($result, $items);
317
318 if (count($response->getData()) < $limit)
319 {
320 $response->setData($result);
321 break;
322 }
323
324 if ($limit < self::LIMIT_MAX)
325 {
326 $limit = self::LIMIT_MAX;
327 }
328
329 $offset += count($response->getData());
330 }
331
332 return new FormResponse(
333 new VkontakteFormBuilder($this::getFieldMapper()),
335 );
336
337 }
338
345 public function getResult(WebHook\Payload\LeadItem $item) : LeadAds\Result
346 {
347 $result = new LeadAds\Result();
348 $result->setId($item->getLeadId());
349 foreach ($item->getAnswers() as $key => $values)
350 {
351 foreach ($values as $index => $value)
352 {
353 if (mb_strpos($value, static::$fieldKeyPrefix) !== 0)
354 {
355 continue;
356 }
357
358 $values[$index] = mb_substr($value, mb_strlen(static::$fieldKeyPrefix));
359 }
360
361 $result->addFieldValues($key, $values);
362 }
363
364 return $result;
365 }
366
374 public function unRegisterGroup(string $groupId) : bool
375 {
376 $this->deleteCallbackServer($groupId);
377
378 return parent::unRegisterGroup($groupId);
379 }
380
386 public function register($formId): Retargeting\Response
387 {
388 if (!isset($formId))
389 {
390 return (new Retargeting\Services\ResponseVkontakte())
391 ->addError(new Error('VK lead ads form register: Empty formId.'))
392 ;
393 }
394 if (!isset($this->accountId))
395 {
396 return (new Retargeting\Services\ResponseVkontakte())
397 ->addError(new Error('VK lead ads form register: Empty accountId.'))
398 ;
399 }
400
401 $isRegister = $this->registerForm($formId);
402 if (!$isRegister)
403 {
404 return (new Retargeting\Services\ResponseVkontakte())
405 ->addError(new Error('VK lead ads form register: Empty formId.'))
406 ;
407 }
408
410 }
411
412 public function loadLeads($formId): Result
413 {
414 if (!isset($formId) || !isset($this->accountId))
415 {
416 return (new Result())
417 ->addError(new Error('Can not load leads'));
418 }
419
420 $limit = self::LIMIT_DEFAULT;
421 $response = $this->loadLeadsByForm($formId,
422 [
423 'limit' => $limit,
424 'offset' => 0,
425 ]
426 );
427
428 if (!$response->isSuccess())
429 {
430 return (new Result())
431 ->addError(new Error('Can not load leads'));
432 }
433
434 $leads = $response->getData();
435 if (count($leads) === $limit)
436 {
437 $limit = self::LIMIT_MAX;
438 while (true)
439 {
440 $response = $this->loadLeadsByForm($formId, [
441 'limit' => $limit,
442 'offset' => count($leads),
443 ]);
444
445 if (!$response->isSuccess())
446 {
447 break;
448 }
449
450 $leads = array_merge($leads, $response->getData());
451
452 if (count($response->getData()) < $limit)
453 {
454 break;
455 }
456 }
457 }
458
459 return (new Result())->setData($leads);
460 }
461
462 protected function loadLeadsByForm(int $formId, array $params): Response
463 {
464 $response = $this->getRequest()->send([
465 'methodName' => 'leadads.form.leads.load',
466 'parameters' => [
467 'form_id' => $formId,
468 'limit' => $params['limit'],
469 'offset' => $params['offset'],
470 ]
471 ]);
472
473 if ($response->isSuccess())
474 {
475 return $response;
476 }
477
479 }
480
481 protected function deleteLinkForm($formId)
482 {
483
484 }
485}
Определения error.php:15
const TYPE_INPUT
Определения field.php:13
const TYPE_PHONE
Определения field.php:32
const TYPE_LOCATION_FULL
Определения field.php:34
const TYPE_LOCATION_COUNTRY
Определения field.php:35
const TYPE_PATRONYMIC_NAME
Определения field.php:26
const TYPE_NAME
Определения field.php:23
const TYPE_BIRTHDAY
Определения field.php:29
const TYPE_AGE
Определения field.php:28
const TYPE_LAST_NAME
Определения field.php:24
const TYPE_EMAIL
Определения field.php:33
const TYPE_LOCATION_CITY
Определения field.php:37
const TYPE_LOCATION_STREET_ADDRESS
Определения field.php:38
Определения form.php:13
registerForm($adsFormId)
Определения form.php:293
$formId
Определения form.php:28
registerFormWebHook($adsFormId, array $parameters=[])
Определения form.php:285
removeFormWebHook($adsFormId)
Определения form.php:308
const TYPE_VKONTAKTE
Определения service.php:20
unRegisterGroup(string $groupId)
Определения formvkontakte.php:374
addCallbackServer(string $secretKey)
Определения formvkontakte.php:208
getResult(WebHook\Payload\LeadItem $item)
Определения formvkontakte.php:345
loadLeadsByForm(int $formId, array $params)
Определения formvkontakte.php:462
static convertField(LeadAds\Field $field)
Определения formvkontakte.php:80
$data['IS_AVAILABLE']
Определения .description.php:13
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$result
Определения get_property_values.php:14
Определения account.php:3
if(empty($signedUserToken)) $key
Определения quickway.php:257
</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."%"
Определения waybill.php:936
if($inWords) echo htmlspecialcharsbx(Number2Word_Rus(roundEx($totalVatSum $params['CURRENCY']
Определения template.php:799
$items
Определения template.php:224
$option
Определения options.php:1711
$response
Определения result.php:21