Задать вопрос
Ответы пользователя по тегу Битрикс24
  • Как выбрать сервер для битрикс24 (коробка)?

    gromdron
    @gromdron Куратор тега Битрикс24
    Работаю с Bitrix24
    У нас стартовая для виртуального сервера:
    - 4GB RAM
    - 2vCPU 2.4 (min)
    - 20GB SSD
    - KVM (не OpenVZ!)
    В год выходит около 12 тысяч.

    Дополнительно берем: Selectel (обачно хранилище).
    Туда КП сгружает все загруженные/сгенерированные пользователем данные. У нас там порядка 80ГБ уже, и в год все это счастье ест где-то 2-3 тыс.руб.

    Всего весь портал ест где-то 15 тыс. рублей в год.

    Если стандартные возможности CRM полностью устраивают и доработок не требуется, то лучше с облака и не съезжать.

    P.S. Если нужные собственные модули/разработки, то окупается во много раз
    Ответ написан
  • Как отправлять заказы с интернет-магазина на horoshop в Битрикс24?

    gromdron
    @gromdron Куратор тега Битрикс24
    Работаю с Bitrix24
    Ну... все относительно просто.

    1) Изучаете API Хорошопа (на уровне "посмотреть что может")
    2) Изучаете API Битрикс24 (на уровне "посмотреть что может")
    3) Определяете что именно из Хорошопа должно уйти в Битрикс24 и что должно уходить из Б24 в Хорошоп.
    4) Покупаете сервер, к нему домен и ssl сертификат. Устаналиваете все что необходимо для работы (например nginx, php, mysql и т.п.).
    5) Пишете приложение обмена. Сначала в одну сторону (Хорошоп - Битрикс), потом если нужно - в другую.
    Ответ написан
    1 комментарий
  • Как в в дизайнере бизнес процессов сменить источник, по определенному имейлу?

    gromdron
    @gromdron Куратор тега Битрикс24
    Работаю с Bitrix24
    Алгоритм простой:

    1) Создаем бизнес-процесс на лиде который запускается при создании
    2) Ставим условие на источник
    3) Изменяем поля документов через соответствующее действие

    У Битрикса есть целый курс по работе с БП. А так же вебинары. Все это в помощь
    Ответ написан
  • Как интегрировать в Битрикс 24 Открытые линии сторонний месенджер?

    gromdron
    @gromdron Куратор тега Битрикс24
    Работаю с Bitrix24
    1) Придумываем коннектору уникальный slug
    2) На примере imconnector.baseconnector разарбатываем собственный компонент коннектора
    3) В \Bitrix\ImConnector\CustomConnectors смотри события на вызовы кастомного коннектора и что именно они должны вернуть

    Документации по этому счастью особо нет (пока, но не известно будет ли), поэтому ковыряние :(
    Ответ написан
    Комментировать
  • Чат-бот для Битрикс24. Как скачать вложения сообщений (фото, аудио и т.п.)?

    gromdron
    @gromdron Куратор тега Битрикс24
    Работаю с Bitrix24
    Ну... попробуйте запросить для Бота права на Диск и при помощи метода dev.1c-bitrix.ru/rest_help/disk/file/disk_file_get.php
    Скачать его.

    По факту: в [urlDownload][default] в ссылке fileId это ID файла на диске и его можно получить.

    Но это скорее хак, чем оф. возможность.
    Ответ написан
  • Можно ли ограничить просмотр только своих комментариев в задаче в Битрикс24?

    gromdron
    @gromdron Куратор тега Битрикс24
    Работаю с Bitrix24
    Понимаю, что вопрос написан очень давно, но все-же напишу ответ, чтобы из поиска люди тоже видели.

    Ответ на вопрос - нет. Роле-правовая система битрикса не подразумевает разделения на чтение только своих комментариев.
    Ответ написан
    Комментировать
  • Где найти информацию по веб-хукам црм Bitrix24?

    gromdron
    @gromdron Куратор тега Битрикс24
    Работаю с Bitrix24
    Увы, документация не поспевает иногда за разработчками.
    Скорее всего (могу ошибаться) pull.watch.extend - подписывается на те же события что и десктоп (для получения нотификаций). pull.config.get - конфигурация push'n'pull (адреса, веб-сокеты, порты, протоколы). Ну и немного счетчиков (сколько личных сообщений, событий, задач и т.п.)
    Ответ написан
    2 комментария
  • Как вывести месяц прописью в Битрикс24?

    gromdron
    @gromdron Куратор тега Битрикс24
    Работаю с Bitrix24
    Это очень геморройно.

    Допустим формат даты у нас такой: d.m.Y H:i:s (что по русски: 22.01.2018 18:07:20)

    На ум приходит следующая конструкция:

    1) Объявляем переменную monthNumber (которая будет содержать номер месяца)
    2) Объявляем переменную monthName (которая будет содержать читаемый месяц)

    Создаем блок изменения переменной и записываем в monthNumber значение{{=substr({=System:Now},3,2)}}
    Что будет означать: что от текущего времени ({=System:Now}), начиная с 3 символа (третий символ - точка) мы возьмем 2.
    Тогда в monthNumber будет число: 01.

    Далее ставим условие и 12 раз повторяем. Если monthNumber=1, то - блок изменения переменной monthName в Январь (ну и так 12 раз).
    Ответ написан
    Комментировать
  • Как подключить личный кабинет?

    gromdron
    @gromdron Куратор тега Битрикс24
    Работаю с Bitrix24
    Готовых решений в связке Битрикс24+Сайт нет.
    Нужно допиливать
    Ответ написан
  • Почему не видно панели Эрмитаж в КП Битрикс?

    gromdron
    @gromdron Куратор тега Битрикс24
    Работаю с Bitrix24
    Очень простой вопрос: с 15 (или 16) версии - его выключили.

    Есть материалы курса: https://helpdesk.bitrix24.ru/open/2006427/
    Которые помогают его вернуть
    Ответ написан
    Комментировать
  • По какому событию отслеживать редактирование структуры компании в Битрикс24?

    gromdron
    @gromdron Куратор тега Битрикс24
    Работаю с Bitrix24
    Добрый день,

    К сожалению, как такового целевого логгирования в Битриксе нет.
    То есть, можно залоггировать отдельные действия, например: изменение пользователя, редактирование файла, изменени структуры.
    Но все данные изменения будут лишь в журнале событий и не будут отражены в публичной части сайта.

    Если смотреть в рамках битрикса, то:
    - редактирование пользователя - событие OnAfterUserUpdate модуля main ( обязательно проверяйте ключ RESULT в $arFields)
    - редактирование подразделения - событие OnAfterIBlockSectionUpdate модуля iblock ( обязательно проверяйте ключи RESULT и IBLOCK_ID для фильтрации только нужных подразделений)
    Аналогично с удалением и добавлением
    Ответ написан
    2 комментария
  • Почему Метод Fetch() в произвольном php коде бизнес процесса Битрикс24 не возращает false?

    gromdron
    @gromdron Куратор тега Битрикс24
    Работаю с Bitrix24
    Мне кажется, что дело не в методе fetch. Основной вопрос заключается в том, что находится в переменной $em, в тот момент, когда находятся элементы.

    Вы же знаете, что при значении $em = true, это аналогично $em = 1, а $em = false - ничего не найдет.

    После присвоения $em допишите код:
    ob_start();
    echo "<pre>";
    var_dump( array(
      'ENTITY_ID' => 'LEAD',
      'VALUE' =>$em , 
      'COMPLEX_ID' => 'EMAIL_WORK' 
    ));
    file_put_contents($_SERVER['DOCUMENT_ROOT'].'/test_bp_val.txt', ob_get_clean(), FILE_APPEND);

    И поймете почему он возвращает то или иное значение
    Ответ написан
  • Как проверять на существование лидов с таким же Email. Битрикс24. Коробочная версия?

    gromdron
    @gromdron Куратор тега Битрикс24
    Работаю с Bitrix24
    Сделать нужно немножечко подругому:

    Изучите нижеследующий код и rest-метод crm.duplicate.findbycomm. Смотрите в /home/bitrix/www/bitrix/modules/crm/classes/general/restservice.php

    use \Bitrix\Main;
    use \Bitrix\Crm;
    
    /* @var string Email, который будем искать */
    $sEmail = 'swap@google.com';
    
    /* @var array ID лидов, которые попадаются под условия */
    $arLeadIds = [];
    
    if ( Main\Loader::IncludeModule('crm') )
    {
    	// Формируем критерий, подсовываем Email
    	$criterion = new Crm\Integrity\DuplicateCommunicationCriterion( Crm\CommunicationType::EMAIL_NAME, $sEmail);
    
    	// Выполняем поиск первых 20 клиентов
    	$duplicate = $criterion->find( \CCrmOwnerType::Lead, 20);
    
    	// Если найдены entity проитерируем их
    	$entities = $duplicate->getEntities();
    	if ( !empty($entities) )
    	{
    		foreach($entities as $entity)
    		{
    			$arLeadIds[] = $entity->getEntityID();
    		}
    	}
    }
    
    // А тут будут ID сделок
    var_dump($arLeadIds);
    Ответ написан
    3 комментария
  • Как опубликовать сообщение в группе с помощью API?

    gromdron
    @gromdron Куратор тега Битрикс24
    Работаю с Bitrix24
    Чтобы отправить сообщение в живую ленту нужно еще более изощренный метод.

    Подключаем модуль Соц.сети:
    CModule::IncludeModule("socialnetwork");

    Чтобы отправить сообщение в ленту, нужно чтобы существовал пост, который будет отправлен в ленту, поэтому создаем сначала пост:

    $arFields = array(
     "TITLE" => "Заголовок записи",
     "DETAIL_TEXT" => "Тело сообщения",
     "BLOG_ID" => 1, //ID отправителя
     "AUTHOR_ID" => 1, //ID блога, в котором будет запись
     "DATE_PUBLISH" => '11.02.2014 09:08', // дада
     "PUBLISH_STATUS" => BLOG_PUBLISH_STATUS_PUBLISH, // Читаем в API
     "ENABLE_TRACKBACK" => 'N',
     "ENABLE_COMMENTS" => 'Y'
    );


    При успешном добавлении ($ID = CBlogPost::Add($arFields);) получим ID blogPost записи

    Затем необходимо отправить это сообщение в ленту, для нам нужен фрагмент кода (заменить соответствующим образом):

    $arEvent = array (
    	'EVENT_ID'     => 'blog_post',
    	'=LOG_DATE'    => 'now()',
    	'TITLE_TEMPLATE' => '#USER_NAME# добавил(а) сообщение "#TITLE#" в блог',
    	'TITLE'    => "Заголовок записи",
    	'MESSAGE'  => "Текст записи",
    	'TEXT_MESSAGE'  => "Текст записи",
    	'MODULE_ID'     => 'blog',
    	'CALLBACK_FUNC' => false,
    	'SOURCE_ID'     => $ID,
    	'ENABLE_COMMENTS'  => 'Y',
    	'RATING_TYPE_ID'   => 'BLOG_POST',
    	'RATING_ENTITY_ID' => $newID,
    	'ENTITY_TYPE' => 'U',
    	'ENTITY_ID'   => '1',
    	'USER_ID'     => '1',
    	'URL' => '/company/personal/user/1/blog/'.$ID.'/',
    );


    Создаём запись в ленте через: CSocNetLog::Add, на выходе получаем eventID (в случае успеха)

    Если все прошло хорошо, то выставляем права на пост (в премере отправляем ВСЕМ ПОЛЬЗОВАТЕЛЯМ G3)

    // Выдает права
    CSocNetLogRights::Add ( $eventID, array ("G3") );
    // Отправляет уведомление о новом сообщении
    CSocNetLog::SendEvent ( $eventID, 'SONET_NEW_EVENT' );


    Радуемся =)

    Все параметры получаются по средствам GetList например.
    Ответ написан
    4 комментария
  • Как добавить фильтр в модуль техподдрежки в Битрикс24?

    gromdron
    @gromdron Куратор тега Битрикс24
    Работаю с Bitrix24
    Насколько я помню, фильтрация по ответственному менеджеру там есть из коробки.
    Фильтрация по теме и по сообщению идут слитно.
    Есть только одна фильтрация, которой в коробке нет - по автору, т.е. он ищет, но только при условии что автор - пользователь портала.
    Ответ написан
    Комментировать
  • Каким образом открытые линии в Битрикс24 собирают лиды со всех источников?

    gromdron
    @gromdron Куратор тега Битрикс24
    Работаю с Bitrix24
    Давайте для начала немного фактов:
    1) Модуль существует и он работает, но обширной документации нет
    2) Он уже больше года не развивается
    3) Даже 1С-Битрикс не использует данный модуль

    Насколько я знаю, решения для интеграции ТП с ОЛ нет (2 независимых модуля) и учитывая п.2 - ждать ее не стоит (ИМХО).
    Что касается распределения тикетов по сотрудникам - для этого можно использовать подписку на событие: OnBeforeTicketAdd и уже там менять ответственного исходя из Ваших нужд.

    Наиболее адекватный вариант - писать свою прослойку для email и ОЛ, благо современный битрикс в коробке позволяет множество кастомизаций (спасибо rest api bitrix24). Так что, если хотите построить техподдержку на базе битрикса, все придется писать с 0.
    Ответ написан
  • Битрикс CRM Коробка. Как добавить пользовательское поле в форму импорта лидов из файла?

    gromdron
    @gromdron Куратор тега Битрикс24
    Работаю с Bitrix24
    Чтобы это поле появилось при импорте, нужно чтобы оно существовало у лида.
    Для этого нужно создать пользовательское поле у лида. А сделать это можно двумя способами:
    1) Через публичные настройки CRM: Настройки -> Настройки форм отчетов -> Пользовательские поля -> Лид: Добавить поле
    2) Через административную панель: Настройки -> Настройки сайтов -> Пользовательские поля -> Добавить.
    В таком случае Вы должны сначала выбрать тип поля, а потом уже объект, который в случае лида будет (как вы верно указали) - CRM_LEAD (насколько я помню, в идеальном случае оно должно не множественным)
    Ответ написан
    4 комментария
  • А как связать сервис Seeneco и Битрикс24?

    gromdron
    @gromdron Куратор тега Битрикс24
    Работаю с Bitrix24
    Если у Seeneco есть API (а я его на сайте не нашел), то можно и даже относительно легко.
    Если у Seeneco нет API, то можно, но уже сложнее.

    Концептуальный ответ - да.
    Ответ написан
    Комментировать
  • Групповая смена ответственного из сделки в контакте и компании в CRM Битрикс, коробочная версия?

    gromdron
    @gromdron Куратор тега Битрикс24
    Работаю с Bitrix24
    Вы правильно нашли, за это отвечает компонент bitrix:crm.deal.list, который лежит в /bitrix/components/bitrix/crm.deal.list/component.php.
    Код несколько запутанный, но работает следующим образом:

    На ~614 сроке ( ~ 614 - 679 ) находится код, который парсит полученные данные и собирает их в массив $actionData
    //region Try to extract user action data
    // We have to extract them before call of CGridOptions::GetFilter() or the custom filter will be corrupted.
    $actionData = array(
    	'METHOD' => $_SERVER['REQUEST_METHOD'],
    	'ACTIVE' => false
    );
    
    if(check_bitrix_sessid())
    {
    	$postAction = 'action_button_'.$arResult['GRID_ID'];
    	$getAction = 'action_'.$arResult['GRID_ID'];
    	//We need to check grid 'controls'
    	$controls = isset($_POST['controls']) && is_array($_POST['controls']) ? $_POST['controls'] : array();
    	if ($actionData['METHOD'] == 'POST' && (isset($controls[$postAction]) || isset($_POST[$postAction])))
    	{
    		CUtil::JSPostUnescape();
    
    		$actionData['ACTIVE'] = true;
    
    		if(isset($controls[$postAction]))
    		{
    			$actionData['NAME'] = $controls[$postAction];
    		}
    		else
    		{
    			$actionData['NAME'] = $_POST[$postAction];
    			unset($_POST[$postAction], $_REQUEST[$postAction]);
    		}
    	...
    	...
    	...
    		$actionData['AJAX_CALL'] = $arResult['IS_AJAX_CALL'];
    	}
    }
    //endregion


    А с ~915 строки начинается непосредственная обработка ( ~915 - 1457):

    // POST & GET actions processing -->
    if($actionData['ACTIVE'])
    {
    	if ($actionData['METHOD'] == 'POST')
    	{
    		if($actionData['NAME'] == 'delete')
    		{
    		...
    		elseif($actionData['NAME'] == 'assign_to')
    		{
    			if(isset($actionData['ASSIGNED_BY_ID']))
    			{
    				$arIDs = array();
    				if ($actionData['ALL_ROWS'])
    				{
    					$arActionFilter = $arFilter;
    					$arActionFilter['CHECK_PERMISSIONS'] = 'N'; // Ignore 'WRITE' permission - we will check it before update.
    					$dbRes = CCrmDeal::GetListEx(array(), $arActionFilter, false, false, array('ID'));
    					while($arDeal = $dbRes->Fetch())
    					{
    						$arIDs[] = $arDeal['ID'];
    					}
    				}
    				elseif (isset($actionData['ID']) && is_array($actionData['ID']))
    				{
    					$arIDs = $actionData['ID'];
    				}
    
    				foreach($arIDs as $ID)
    				{
    					if (!CCrmDeal::CheckUpdatePermission($ID, $userPermissions))
    					{
    						continue;
    					}
    
    					$DB->StartTransaction();
    
    					$arUpdateData = array(
    						'ASSIGNED_BY_ID' => $actionData['ASSIGNED_BY_ID']
    					);
    
    					if($CCrmDeal->Update($ID, $arUpdateData, true, true, array('DISABLE_USER_FIELD_CHECK' => true)))
    					{
    						$DB->Commit();
    
    						$arErrors = array();
    						CCrmBizProcHelper::AutoStartWorkflows(
    							CCrmOwnerType::Deal,
    							$ID,
    							CCrmBizProcEventType::Edit,
    							$arErrors
    						);
    					}
    					else
    					{
    						$DB->Rollback();
    					}
    				}
    			}
    		}
    		...
    	}
    }
    // <-- POST & GET actions processing


    Но есть маленький нюанс, если Вам нужно менять ответственного в связанных сущностях, кастомизация данного кода будет не лучшим решением.
    В таком случае у Вас будет задвоение, например ответственного можно поменять через массовую смену ответственного в списке, через редактирование сделки, через блок действия бизнес-процесса и так далее. И все это разные механизмы. Общее у них только одно - они все используют события на изменения/добавление.
    Ответ написан
  • Битрикс CRM Получить ID контакта?

    gromdron
    @gromdron Куратор тега Битрикс24
    Работаю с Bitrix24
    Есть как минимум 2 варианта (без прямых запросов в базу) как это сделать:

    1) Высокоуровневый (работает всегда). Метод с поддержкой обратной совместимости: CCrmContact::GetList (bxapi.ru/src/?id=183244)

    Применение (за основу взял код описанный Артем):

    /* @var array Список контактов */
    $arContacts = array();
    
    if ( \Bitrix\Main\Loader::IncludeModule('crm') )
    {
    	/* @var array Сортировка полученного списка контактов */
    	$arOrder  = array('ID' => 'DESC');
    
    	/* @var array Условия получаемого списка контактов */
    	$arFilter = array(
    		"NAME"      => "Имя",
    		"LAST_NAME" => "Фамилия",
    		'CHECK_PERMISSIONS' => 'N' // Данный ключ необходим для того чтобы получить всех пользоватей,
    								   // иначе, будет найден только если ответственным за него является тот,
    								   // под кем запускается скрипт в битриксе
    	);
    
    	/* @var array Получаемые поля для списка контактов */
    	$arSelect = array(
    		'ID'
    	);
    
    	// NOTE: Запрашивайте только необходимые поля
    	$res = CCrmContact::GetList( $arOrder, $arFilter, $arSelect );
    
    	while( $arContact = $res->fetch() )
    	{
    		$arContacts[ $arContact['ID'] ] = $arContact['ID'];
    	}
    }
    
    // Тут в $arContacts либо пустой массив, либо массив с ID контактами, которые соответствуют условию поиска


    2) Низкоуровневый DataMapper (новый подход d7)

    use \Bitrix\Main\Loader;
    use \Bitrix\Crm;
    
    /* @var array Список контактов */
    $arContacts = array();
    
    if ( Loader::IncludeModule('crm') )
    {
    
    	$resContacts = Crm\ContactTable::getList(array(
    		'select' => array('ID'),
    		'filter' => array(
    			"NAME"      => "Имя",
    			"LAST_NAME" => "Фамилия",
    		),
    		'order' => array('ID' => 'DESC')
    	));
    
    	while( $arContact = $resContacts->fetch() )
    	{
    		$arContacts[ $arContact['ID'] ] = $arContact['ID'];
    	}
    
    	/*
    	Начиная с 17 версии (вроде бы), можно делать так:
    	foreach( $resContacts as $arContact)
    	{
    		$arContacts[ $arContact['ID'] ] = $arContact['ID'];
    	}
    	вместо while цикла
    	*/
    }


    Преимущество первого подхода:
    - Работает всегда, как для новых, так и для старых проектов
    - Можно использовать уровни доступа

    Преимущество нового подхода:
    - Технологически универсален за счет d7 (можно в runtime прибавлять связи, доставать связанные сущности и т.п.)
    - В DataMapper есть технология кеширования, т.е. можно закешировать результат просто добавив в массив getList еще один ключик
    - Субъективно код легче воспринимается
    Ответ написан
    3 комментария