Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
formvkontakte.php
1<?php
2
4
20
21
28{
29 public const TYPE_CODE = LeadAds\Service::TYPE_VKONTAKTE;
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()),
149 $response
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
294 protected function encodeString($text, $length = 60): string
295 {
296 $text = Encoding::convertEncoding(
297 $text,
298 Context::getCurrent()->getCulture()->getCharset(),
299 'UTF-8'
300 );
301
302 return mb_substr($text, 0, $length);
303 }
304
311 public function getList() : FormResponse
312 {
313 $limit = self::LIMIT_DEFAULT;
314 $offset = 0;
315 $result = [];
317 while (true)
318 {
319 $response = $this->getRequest()->send([
320 'methodName' => 'leadads.form.list',
321 'parameters' => [
322 'limit' => $limit,
323 'offset' => $offset,
324 ]
325 ]);
326 $items = array_filter($response->getData(), fn ($item) => ((int)$item['status'] === self::STATUS_FORM_ACTIVE));
327 $result = array_merge($result, $items);
328
329 if (count($response->getData()) < $limit)
330 {
331 $response->setData($result);
332 break;
333 }
334
335 if ($limit < self::LIMIT_MAX)
336 {
337 $limit = self::LIMIT_MAX;
338 }
339
340 $offset += count($response->getData());
341 }
342
343 return new FormResponse(
344 new VkontakteFormBuilder($this::getFieldMapper()),
345 $response
346 );
347
348 }
349
356 public function getResult(WebHook\Payload\LeadItem $item) : LeadAds\Result
357 {
358 $result = new LeadAds\Result();
359 $result->setId($item->getLeadId());
360 foreach ($item->getAnswers() as $key => $values)
361 {
362 foreach ($values as $index => $value)
363 {
364 if (mb_strpos($value, static::$fieldKeyPrefix) !== 0)
365 {
366 continue;
367 }
368
369 $values[$index] = mb_substr($value, mb_strlen(static::$fieldKeyPrefix));
370 }
371
372 $result->addFieldValues($key, $values);
373 }
374
375 return $result;
376 }
377
385 public function unRegisterGroup(string $groupId) : bool
386 {
387 $this->deleteCallbackServer($groupId);
388
389 return parent::unRegisterGroup($groupId);
390 }
391
397 public function register($formId): Retargeting\Response
398 {
399 if (!isset($formId))
400 {
401 return (new Retargeting\Services\ResponseVkontakte())
402 ->addError(new Error('VK lead ads form register: Empty formId.'))
403 ;
404 }
405 if (!isset($this->accountId))
406 {
407 return (new Retargeting\Services\ResponseVkontakte())
408 ->addError(new Error('VK lead ads form register: Empty accountId.'))
409 ;
410 }
411
412 $isRegister = $this->registerForm($formId);
413 if (!$isRegister)
414 {
415 return (new Retargeting\Services\ResponseVkontakte())
416 ->addError(new Error('VK lead ads form register: Empty formId.'))
417 ;
418 }
419
421 }
422
423 public function loadLeads($formId): Result
424 {
425 if (!isset($formId) || !isset($this->accountId))
426 {
427 return (new Result())
428 ->addError(new Error('Can not load leads'));
429 }
430
431 $limit = self::LIMIT_DEFAULT;
432 $response = $this->loadLeadsByForm($formId,
433 [
434 'limit' => $limit,
435 'offset' => 0,
436 ]
437 );
438
439 if (!$response->isSuccess())
440 {
441 return (new Result())
442 ->addError(new Error('Can not load leads'));
443 }
444
445 $leads = $response->getData();
446 if (count($leads) === $limit)
447 {
448 $limit = self::LIMIT_MAX;
449 while (true)
450 {
451 $response = $this->loadLeadsByForm($formId, [
452 'limit' => $limit,
453 'offset' => count($leads),
454 ]);
455
456 if (!$response->isSuccess())
457 {
458 break;
459 }
460
461 $leads = array_merge($leads, $response->getData());
462
463 if (count($response->getData()) < $limit)
464 {
465 break;
466 }
467 }
468 }
469
470 return (new Result())->setData($leads);
471 }
472
473 protected function loadLeadsByForm(int $formId, array $params): Response
474 {
475 $response = $this->getRequest()->send([
476 'methodName' => 'leadads.form.leads.load',
477 'parameters' => [
478 'form_id' => $formId,
479 'limit' => $params['limit'],
480 'offset' => $params['offset'],
481 ]
482 ]);
483
484 if ($response->isSuccess())
485 {
486 return $response;
487 }
488
490 }
491
492 protected function deleteLinkForm($formId)
493 {
494
495 }
496}
static getCurrent()
Definition context.php:241
addError(Error $error)
Definition result.php:50
registerForm($adsFormId)
Definition form.php:293
registerFormWebHook($adsFormId, array $parameters=[])
Definition form.php:285
removeFormWebHook($adsFormId)
Definition form.php:308
getResult(WebHook\Payload\LeadItem $item)
loadLeadsByForm(int $formId, array $params)
static convertField(LeadAds\Field $field)