Русский
Русский
English
Статистика
Реклама

Bitrix24

Битрикс24. Играемся с настройками и оптимизируем проект

03.02.2021 20:08:13 | Автор: admin
В этой статье мы расскажем, как оптимизировать крупный проект в Битрикс24 и увеличить его производительность в 3 раза, изменяя настройки MySQL и режим питания CPU.

Дано


Корпоративный портал в Битрикс24, рассчитанный на несколько сотен пользователей, c ~300 Гб файлов и ~80 Гб БД на выделенном сервере с BitrixVM.

До изменения настроек показатели были следующими:



Стандартный тест производительности в панели администратора Битрикс

Из всех параметров стоит обратить особое внимание на работу с MySQL и Конфигурацию PHP. Именно эти показатели особенно важны для нас, так как они косвенно отражают уровень производительности проекта.

Запрос клиента


Наш клиент хотел не только перенести проект на новый выделенный сервер, но и улучшить параметры производительности. Например, среди сложностей можно назвать отсутствие возможности делать дампы базы данных на исходном сервере, а также медленную работа самого портала.

Решение


Настройки MySQL первое, с чем мы начинаем работать.

Заменим стандартные значения BitrixVM на:

explicit_defaults_for_timestamp = 1expire_logs_days = 10max_binlog_size = 100Mmax_allowed_packet = 128Mtransaction-isolation = READ-COMMITTEDperformance_schema = OFFsql_mode = ""# Cache parametersquery_cache_type = 1query_cache_size=16Mquery_cache_limit=4Mkey_buffer_size=256Mjoin_buffer_size=2Msort_buffer_size=4M# Parameters for temporary tablestmpdir = /tmptmp_table_size=128Mmax_heap_table_size=128Mthread_cache_size = 4table_open_cache = 2048# InnoDB parametersinnodb_file_per_tableinnodb_buffer_pool_size = 8192Minnodb_buffer_pool_instances = 1innodb_flush_log_at_trx_commit = 0innodb_flush_method = O_DIRECTinnodb_strict_mode = OFF# Database charset parameterscharacter-set-server=utf8collation-server=utf8_general_ciinit-connect="SET NAMES utf8"[mysqldump]quickquote-namesdefault-character-set = utf8

Следующий шаг изменим режим питания CPU, так как Битрикс любит большую частоту процессора.

В зависимости от количества ядер меняем в каждом
файле /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor powersave на performance.

Далее проверим результат:



Мы видим, что больше всего изменилась работа с MySQL: параметры запись и изменение выросли почти в 3 раза; показатель чтение вырос в 5 раз. Это значит, что при обращении сайта к базе данных этот тип операции будет выполняться в несколько раз быстрее. Как следствие, вырастет и общая производительность сайта.

Из-за изменения режима питания CPU (это возможно, так как используется выделенный сервер) увеличилось количество операций на CPU.

Теперь необходимо отредактировать настройки для OPcache.

В файле /etc/php.d/10-opcache.ini заменяем его исходное значение на:

zend_extension=opcache.soopcache.enable = 1opcache.enable_cli = 1opcache.memory_consumption = 256opcache.max_file_size = 2Mopcache.interned_strings_buffer = 64opcache.max_accelerated_files = 130987opcache.fast_shutdown = 1opcache.revalidate_freq = 1opcache.fast_shutdown=1opcache.save_comments=1opcache.load_comments=1opcache.use_cwd = 1

Примечание: Тест Битрикс сообщит вам, что параметр opcache.revalidate_freq должен иметь значение 0 а не 1, но с указанным нами он будет работать лучше.

Сам параметр opcache.revalidate_freq отвечает за проверку кеша: при значении 0 она выполняется каждый раз при запуске скрипта, а при значении 1 раз в секунду.

После изменения настроек проверяем результат:



Из таблицы следует, что показатель работы с MySQL еще немного вырос. В то же время операции на CPU и общая производительность Битрикс увеличились значительно за счет изменения настроек PHP и кеширования скриптов.

Вывод


Благодаря таким несложным изменениям в настройках, мы смогли увеличить производительность проекта в 3 раза, а взаимодействие с БД от 3 до 5 раз (на основании общей оценки теста Битрикс). Работой проекта на новом сервере наш клиент полностью доволен. We did it!

В данном способе оптимизации мы сделали акцент на основных моментах, с которыми взаимодействует Битрикс, а также на сам тест. Клиенты часто обращают внимание именно на него.

Среди других способов повышения производительности Битрикс можно назвать установку и настройку кеширующего сервиса (например, Redis). Показатель производительности в CMS может упасть, но общая работа сайта должна быть лучше. Кроме того, можно использовать php-fpm, но в нашем случае переделывать ОС, изначально настроенную под Битрикс, было бы нерационально.

Также можно еще поиграться с настройками MySQL. Они индивидуальны для каждого проекта и конфигурации, поэтому единого идеального рецепта не существует. Будет интересно узнать ваши лайфхаки по оптимизации проектов в Битрикс. Делитесь мнением в комментариях.
Подробнее..

Разбираемся с FreePBX и интегрируем его с Битрикс24 и не только

09.09.2020 16:16:51 | Автор: admin

Битрикс24 - это огромный комбайн, который совмещает и CRM, и документооборот, и учет и еще много разных вещей, которые очень нравятся менеджерам и не очень нравятся IT персоналу. Портал используют очень много небольших и средних компаний, в том числе небольшие клиники, производственники и даже салоны красоты. Основной функцией, которую "любят" менеджеры является интеграция телефонии и CRM, когда любой звонок сразу фиксируется в CRM, создаются карточки клиента, при входящем отображается информация о клиенте и сразу видно кто он такой, что ему можно продать и сколько он должен. Но телефония от Битрикс24 и ее интеграция с CRM стоит денег, иногда немалых. В статье я расскажу опыт интеграции с открытыми инструментами и популярной IP АТС FreePBX, а также рассмотрю логику работы различных частей

Я работаю на аутсорсе в компании, которая занимается продажей и настройкой, интеграцией IP телефонии. Когда меня спросили, можем ли мы вон той вот и вот этой вот компании предложить что то для интеграции Битрикс24 с АТС, которые стоят у клиентов, а также с виртуальными АТС на различных VDS компании, я пошел в Гугл. И он мне конечно же выдал ссылку на статью в хабр, где есть и описание, и github, и вроде все работает. Но при попытке попользоваться этим решением вылезло, что Битрикс24 уже не тот, что ранее, и надо многое переделывать. Кроме того, FreePBX это вам не голый астериск, тут думать надо как совместить удобство использования и хардкорный диалплан в конфиг-файлах.

Изучаем логику работы

Итак для начала, как все это должно работать. При поступления звонка извне на АТС (событие SIP INVITE от провайдера) начинается обработка диалплана(плана набора, dialplan) - правил, что и в каком порядке делать со звонком. Из первого пакета можно получить много информации, которую потом можно использовать в правилах. Отличным инструментом для изучения внутренностей SIP является анализатор sngrep (ссылка) который просто ставится в популярных дистрибутивах через apt install/yum install и подобное, но можно и из исходников собрать. Посмотрим лог звонка в sngrep

В упрощенном виде диалплан занимается только первым пакетом, иногда также в процессе разговора совершается перевод звонков, нажатия кнопок (DTMF), разные интересности типа FollowMe, RingGroup, IVR и прочего.

Что внутри Invite пакета

Собственно большинство простых диалпланов работают с первыми двумя полями и вся логика крутится вокруг DID и CallerID. DID - куда звоним, CallerID - кто звонит.

Но ведь у нас фирма а не один телефон - и значит в АТС скорее всего есть группы вызова (одновременный/последовательный звонок нескольких аппаратов) на городских номерах (Ring Group), IVR (Здравствуйте, вы позвонили... Нажмите один для...), Автоответчики (Phrases), Временные условия (Time Conditions), Переадресация на другие номера или на сотовый (FollowMe, Forward). Это значит, что однозначно определить кому на самом деле придет вызов и с кем будет разговор при поступлении вызова очень сложно. Вот пример начала прохождения типового вызова в АТС наших клиентов

После успешного входа звонка в АТС происходит путешествие его по диалплану в разных "контекстах". Контекст с точки зрения Asterisk - это нумерованный набор команд, каждая из которых содержит фильтр по набранному номеру (он называется exten, для наружного вызова на начальном этапе exten=DID). Командами в строке диалплана может быть все что угодно - внутренние функции (например позвонить внутреннему абоненту - Dial(), положить трубку - Hangup()), условные операторы (IF, ELSE, ExecIF и подобные), переходы к другим правилам этого контекста (Goto, GotoIF), переход другим контекстам в виде вызова функций (Gosub, Macro). Отдельно стоит директива include имя_контекста, которая добавляет команды другого контекста в конец текущего контекста. Команды, включенные через include всегда выполняются после команд текущего контекста.

Вся логика работы FreePBX построена на включении друг в друга разных контекстов через include и вызов через Gosub, Macro и обработчики Handler. Рассмотрим контекст входящих вызовов FreePBX

Вызов проходит по всем контекстам сверху вниз по очереди, в кажом контексте могут быть вызовы других контекстов как макросов (Macro), функций(Gosub) или просто переходы (Goto), поэтому реальное дерево того, что вызывается можно отследить только в логах.

Типовая схема настройки типичной офисной АТС показана ниже. При вызове во входящих маршрутах ищется DID, по нему проверяются временные условия, если все в порядке - запускается голосовое меню. Из него по кнопке 1 или таймауту выход на группу дозвона операторов. После окончания звонка вызывается макрос hangupcall, после которого ничего уже в диалплане выполнить не удастся, кроме специальных обработчиков (hangup handler).

Где в этом алгоритме звонка мы должны поставлять информацию о начале звонка в CRM, где начинать запись, где оканчивать запись и отсылать ее вместе с информацией о звонке на CRM?

Интеграция с внешними системами

Что такое интеграция АТС и CRM? Это настройки и программы, которые конвертируют данные и события между двумя этими платформами и пересылают друг другу. Самым распространенным способом взаимодействия независимых систем является API, а самым популярным способом доступа к API является HTTP REST. Но только не для asterisk.

Внутри Asterisk есть:

  • AGI - синхронный вызов внешних программ/компонентов, используется в основном в диалплане, есть библиотеки типа phpagi, PAGI

  • AMI - текстовый TCP сокет, работающий по принципу подписки на события и ввода текстовых команд, напоминает SMTP изнутри, умеет отслеживать события и управлять вызовами, ,есть библиотека PAMI - самая популярная для создания связи с Asterisk

Пример вывода AMI

Event: NewchannelPrivilege: call,allChannel: PJSIP/VMS_pjsip-0000078bChannelState: 4ChannelStateDesc: RingCallerIDNum: 111222CallerIDName: 111222ConnectedLineNum: ConnectedLineName: Language: enAccountCode:Context: from-pstnExten: sPriority: 1Uniqueid: 1599589046.5244Linkedid: 1599589046.5244

  • ARI - смесь того, другого, все через REST, WebSocket, в формате JSON - но вот со свежими библиотеками и обертками не очень, на вскидку нашлись (phparia, phpari) которые становились в своем развитии года 3 назад.

Пример вывода ARI при инициации звонка

{ "variable":"CallMeCallerIDName", "value":"111222", "type":"ChannelVarset", "timestamp":"2020-09-09T09:38:36.269+0000", "channel":{ "id":"1599644315.5334", "name":"PJSIP/VMSpjsip-000007b6", "state":"Ring", "caller":{ "name":"111222", "number":"111222" }, "connected":{ "name":"", "number":"" }, "accountcode":"", "dialplan":{ "context":"from-pstn", "exten":"s", "priority":2, "appname":"Stasis", "appdata":"hello-world" }, "creationtime":"2020-09-09T09:38:35.926+0000", "language":"ru" }, "asteriskid":"48:5b:aa:aa:aa:aa", "application":"hello-world" }

Удобство или неудобство, возможность или невозможность работы с тем или иным API определяются задачами, которые необходимо решить. Задачи для интеграции с CRM следующие:

  • Отследить начало вызова, куда его перевели, вытащить CallerID, DID, времена начала и конца, может быть данные из директории (для поиска связи телефона и пользователя CRM)

  • Начать и окончить запись звонка, сохранить в нужном формате, сообщить по окончании записи где лежит файл

  • Инициировать звонок по внешнему событию (из программы), позвонить внутреннему номеру, внешнему и соединить их

  • Опционально: интегрировать с CRM, группами дозвона и FollowME для автоматического перевода звонков при отсутствии на месте(по информации CRM)

Все эти задачи можно решить через AMI или ARI, но ARI предоставляет гораздо меньше информации, нет многих событий, не отслеживаются многие переменные, которые в AMI все таки есть (например вызовы макросов, задание переменных внутри макросов, в том числе запись звонков). Поэтому, для правильного и точного отслеживания - выберем пока AMI (но не окончательно). Кроме того (ну а куда ж без этого, мы люди ленивые) - в исходной работе (статья в хабр) используют PAMI. *Потом надо попробовать переписать на ARI, но не факт что получится.

Придумываем интеграцию заново

Для того, чтоб наш FreePBX мог сообщать в AMI простыми способами о начале звонка, времени окончания, номерах, именах записанных файлов, рассчитывать длительность звонка проще всего воспользоваться тем же трюком, что и исходные авторы - ввести свои переменные и парсить вывод на их присутствие. PAMI предлагает это делать просто через функцию-фильтр.

Вот пример задания своей переменной для времени начала звонка (s - это специальный номер в диалплане, который выполняется ДО начала поиска по DID)

[ext-did-custom]exten => s,1,Set(CallStart=${STRFTIME(epoch,,%s)})
Пример AMI события по этой строке

Event: Newchannel

Privilege: call,all

Channel: PJSIP/VMS_pjsip-0000078b

ChannelState: 4

ChannelStateDesc: Ring

CallerIDNum: 111222

CallerIDName: 111222

ConnectedLineNum:

ConnectedLineName:

Language: en

AccountCode:

Context: from-pstn

Exten: s

Priority: 1

Uniqueid: 1599589046.5244

Linkedid: 1599589046.5244

Application: Set AppData:

CallStart=1599571046

Поскольку FreePBX перезаписывает файлы extention.conf и extention_additional.conf, мы будем использовать файл extention_custom.conf

Полный код extention_custom.conf
[globals];; Проверьте пути и права на папки - юзер asterisk должен иметь права на запись;; Сюда будет писаться разговорыWAV=/var/www/html/callme/records/wav MP3=/var/www/html/callme/records/mp3;; По этим путям будет воспроизводится и скачиваться записьURLRECORDS=https://www.host.ru/callmeplus/records/mp3;; Адрес для калбека при исходящем вызовеURLPHP=https://www.host.ru/callmeplus;; Да пишем разговорыRECORDING=1;; Это макрос для записи разговоров в нашу папку. ;; Можно использовать и системную запись, но пока пусть будет эта - ;; она работает[recording]exten => ~~s~~,1,Set(LOCAL(calling)=${ARG1})exten => ~~s~~,2,Set(LOCAL(called)=${ARG2})exten => ~~s~~,3,GotoIf($["${RECORDING}" = "1"]?4:14)exten => ~~s~~,4,Set(fname=${UNIQUEID}-${STRFTIME(${EPOCH},,%Y-%m-%d-%H_%M)}-${calling}-${called})exten => ~~s~~,5,Set(datedir=${STRFTIME(${EPOCH},,%Y/%m/%d)})exten => ~~s~~,6,System(mkdir -p ${MP3}/${datedir})exten => ~~s~~,7,System(mkdir -p ${WAV}/${datedir})exten => ~~s~~,8,Set(monopt=nice -n 19 /usr/bin/lame -b 32  --silent "${WAV}/${datedir}/${fname}.wav"  "${MP3}/${datedir}/${fname}.mp3" && rm -f "${WAV}/${fname}.wav" && chmod o+r "${MP3}/${datedir}/${fname}.mp3")exten => ~~s~~,9,Set(FullFname=${URLRECORDS}/${datedir}/${fname}.mp3)exten => ~~s~~,10,Set(CDR(filename)=${fname}.mp3)exten => ~~s~~,11,Set(CDR(recordingfile)=${fname}.wav)exten => ~~s~~,12,Set(CDR(realdst)=${called})exten => ~~s~~,13,MixMonitor(${WAV}/${datedir}/${fname}.wav,b,${monopt})exten => ~~s~~,14,NoOp(Finish if_recording_1)exten => ~~s~~,15,Return();; Это основной контекст для начала разговора[ext-did-custom];; Это хулиганство, делать это так и здесь, но работает - добавляем к номеру '8'exten =>  s,1,Set(CALLERID(num)=8${CALLERID(num)});; Тут всякие переменные для скриптаexten =>  s,n,Gosub(recording,~~s~~,1(${CALLERID(number)},${EXTEN}))exten =>  s,n,ExecIF(${CallMeCallerIDName}?Set(CALLERID(name)=${CallMeCallerIDName}):NoOp())exten =>  s,n,Set(CallStart=${STRFTIME(epoch,,%s)})exten =>  s,n,Set(CallMeDISPOSITION=${CDR(disposition)});; Самое главное! Обработчик окончания разговора. ;; Обычные пути обработки конца через (exten=>h,1,чтототут) в FreePBX не работают - Macro(hangupcall,) все портит. ;; Поэтому вешаем Hangup_Handler на окончание звонкаexten => s,n,Set(CHANNEL(hangup_handler_push)=sub-call-from-cid-ended,s,1(${CALLERID(num)},${EXTEN}));; Обработчик окончания входящего вызова[sub-call-from-cid-ended];; Сообщаем о значениях при конце звонкаexten => s,1,Set(CDR_PROP(disable)=true)exten => s,n,Set(CallStop=${STRFTIME(epoch,,%s)})exten => s,n,Set(CallMeDURATION=${MATH(${CallStop}-${CallStart},int)});; Статус вызова - Ответ, не ответ...exten => s,n,Set(CallMeDISPOSITION=${CDR(disposition)})exten => s,n,Return;; Обработчик исходящих вызовов - все аналогичено[outbound-allroutes-custom];; Записьexten => _.,1,Gosub(recording,~~s~~,1(${CALLERID(number)},${EXTEN}));; Переменныеexten => _.,n,Set(__CallIntNum=${CALLERID(num)})exten => _.,n,Set(CallExtNum=${EXTEN})exten => _.,n,Set(CallStart=${STRFTIME(epoch,,%s)})exten => _.,n,Set(CallmeCALLID=${SIPCALLID});; Вешаем Hangup_Handler на окончание звонкаexten => _.,n,Set(CHANNEL(hangup_handler_push)=sub-call-internal-ended,s,1(${CALLERID(num)},${EXTEN}));; Обработчик окончания исходящего вызова[sub-call-internal-ended];; переменныеexten => s,1,Set(CDR_PROP(disable)=true)exten => s,n,Set(CallStop=${STRFTIME(epoch,,%s)})exten => s,n,Set(CallMeDURATION=${MATH(${CallStop}-${CallStart},int)})exten => s,n,Set(CallMeDISPOSITION=${CDR(disposition)});; Вызов скрипта, который сообщит о звонке в CRM - это исходящий, ;; так что по факту окончанияexten => s,n,System(curl -s ${URLPHP}/CallMeOut.php --data action=sendcall2b24 --data ExtNum=${CallExtNum} --data call_id=${SIPCALLID} --data-urlencode FullFname='${FullFname}' --data CallIntNum=${CallIntNum} --data CallDuration=${CallMeDURATION} --data-urlencode CallDisposition='${CallMeDISPOSITION}')exten => s,n,Return

Особенность и отличием от оригинального диалплана авторов исходной статьи -

  • Диалплан в формате .conf, так как этого хочет FreePBX (да он умеет .ael, но не все версии и не всегда это удобно)

  • Вместо обработки окончания через exten=>h введена обработка через hangup_handler, потому что FreePBX диалплан заработал только с ним

  • Поправлена строка вызова скрипта, добавлены кавычки и внешний номер звонка ExtNum

  • Обработки вынесена в _custom контексты и позволяют не трогать и не править конфиги FreePBX - входящие через [ext-did-custom], исходящие через [outbound-allroutes-custom]

  • Нет привязки к номерам - файл универсален и нуждается в настройке только пути и ссылка на сервер

Для начала работы нужно еще пустить скрипты в AMI по логину и паролю - для этого в FreePBX тоже есть _custom файл

Файл manager_custom.conf
;;  это логин[callmeplus];; это парольsecret = trampampamturlaladeny = 0.0.0.0/0.0.0.0;; я работаю с локальной машиной - но если надо, можно и другие прописатьpermit = 127.0.0.1/255.255.255.255read = system,call,log,verbose,agent,user,config,dtmf,reporting,cdr,dialplanwrite = system,call,agent,log,verbose,user,config,command,reporting,originate

Эти оба файла надо поместить в /etc/asterisk, затем перечитать конфиги (или перезапустить астериск)

# astrisk -rv  Connected to Asterisk 16.6.2 currently running on freepbx (pid = 31629)#freepbx*CLI> dialplan reload     Dialplan reloaded.#freepbx*CLI> exit

Теперь перейдем к PHP

Инициализация скриптов и создание сервиса

Поскольку схема работы с Битрикс 24, сервисом для AMI не совсем проста и прозрачна, на ней надо остановится отдельно. Астериск при активации AMI просто открывает порт и все. При присоединении клиента она запрашивает авторизацию, потом клиент подписывается на нужные события. События приходят простым текстом, который PAMI преобразует в структурированные объекты и предоставляет возможность задание функции фильтрации только по интересующим событиям, полям, номерам и т.д.

Как только звонок поступает, возникает событие NewExten начиная с родительского контекста [from-pstn], затем идут все события по порядку следования строк в контекстах. При получении информации из заданных в диалплане _custom переменных CallMeCallerIDName и CallStart вызывается

  1. Функция запроса UserID, соответствующий внутреннему номеру, куда пришел звонок. А если это группа дозвона? Вопрос политический, надо создать звонок всем сразу (когда звонят все сразу) или создавать по мере обзвона при поочередном звонке? У большинства клиентов стоит стратегия Fisrt Available, поэтому с этим нет проблем, звонит только один. Но решать вопрос надо

  2. Функция регистрации звонка в Битрикс24, которая возвращает CallID, необходимый потом для сообщения о параметрах звонка и ссылке на запись. Требует или внутренний номер или UserID

После окончания звонка вызывается функция загрузки записи, которая одновременно сообщает статус завершения звонка (Занят, Нет ответа, Успех), а также загружает ссылку на mp3 файл с записью (если есть).

Поскольку модуль CallMeIn.php должен работать непрерывно, для него был создан SystemD файл запуска callme.service, который надо положить в /etc/systemd/system/callme.service

[Unit]Description=CallMe[Service]WorkingDirectory=/var/www/html/callmeplusExecStart=/usr/bin/php /var/www/html/callmeplus/CallMeIn.php 2>&1 >>/var/log/callmeplus.logExecStop=/bin/kill -WINCH ${MAINPID}KillSignal=SIGKILLRestart=on-failureRestartSec=10s#тут надо смотреть,какие права на папки#User=www-data  #Ubuntu - debian#User=nginx #Centos[Install]WantedBy=multi-user.target

инициализация и запуск скрипта происходит через systemctl или service

# systemctl enable callme# systemctl start callme

Сервис будет сам перезапускаться по необходимости (при падениях). Сервис слежения за входящими не требует установки веб сервера, нужен только php (который точно есть на сервере FeePBX). Но при отсутствии доступа к записям звонков через Веб сервер (еще и с https) не будет возможности прослушивать записи разговоров.

Теперь поговорим про исходящие звонки. У скрипта CallMeOut.php две функции:

  • Инициация звонка при поступлении запроса на php скрипт (в том числе по кнопке "Позвонить" в самом битриксе). Без веб сервера не работает, запрос поступает через HTTP POST, в запросе содержится токен

  • Сообщение о звонке, его параметрах и записях в Битрикс. Происходит по инициативе Asterisk в диалплане [sub-call-internal-ended] при окончании звонка

Веб сервер нужен только для двух вещей - загрузка файлов записей битриксом (по HTTPS) и вызов скрипта CallMeOut.php. Можно использовать встроенный сервер FreePBX, файлы для которого лежат /var/www/html, можно установить другой сервер или прописать другой путь.

Веб сервер

Оставим настройку веб сервера на самостоятельное изучение (тыц, тыц, тыц). Если у вас нет домена, можно попробовать FreeDomain( https://www.freenom.com/ru/index.html), которые на халяву дадут вам имя для вашего белого IP (не забудьте пробросить порты 80, 443 через роутер, если внешний адрес есть только на нем). Если вы только создали DNS домен, то надо подождать (от 15 минут до 48 часов) пока все сервера прогрузятся. По опыту работы с отечественными порвайдерами - от 1 часа до суток.

Автоматизация установки

На github начата разработка инсталятора, чтоб можно было устанавливать еще проще. Но гладко было на бумаге - пока устанавливаем все это вручную, благо после ковыряния во всем этом стало кристально ясно , что с кем дружит, кто куда ходит и как это дебажить. Инсталлятора пока нет (

Docker

Если хочется быстро попробовать решение - есть вариант с Docker - быстро создать контейнер, дать ему порты наружу, подсунуть файлы настроек и попробовать (это вариант с LetsEncrypt контейнером, если сертификат уже есть, просто нужно перенаправить обратный прокси на веб сервер FreePBX (ему мы дали другой порт - 88), LetsEncrypt в докере по мотивам этой статьи

Запускать файл надо в скачанной папке проекта (после git clone), но предварительно залезть в конфиги астериска (папка asterisk) и прописать там пути к записям и URL вашего сайта

version: '3.3'services:  nginx:    image: nginx:1.15-alpine    ports:      - "80:80"      - "443:443"    volumes:      - ./nginx/ssl_docker.conf:/etc/nginx/conf.d/ssl_docker.conf  certbot:    image: certbot/certbot  freepbx:    image: flaviostutz/freepbx    ports:      - 88:80 # для настройки      - 5060:5060/udp      - 5160:5160/udp      - 127.0.0.1:5038:5038 # для CallMeOut.php#      - 3306:3306      - 18000-18100:18000-18100/udp    restart: always    environment:      - ADMIN_PASSWORD=admin123    volumes:      - backup:/backup      - recordings:/var/spool/asterisk/monitor      - ./callme:/var/www/html/callme      - ./systemd/callme.service:/etc/systemd/system/callme.conf      - ./asterisk/manager_custom.conf:/etc/asterisk/manager_custom.conf      - ./asterisk/extensions_custom.conf:/etc/asterisk/extensions_custom.conf#      - ./conf/startup.sh:/startup.shvolumes:  backup:  recordings:

Этот файл docker-compose.yaml, запускается через

docker-compose up -d

Если nginx не запустился, значит что то не так с конфигурацией в папке nginx/ssl_docker.conf

Другие интеграции

А почему бы заодно не сунуть несколько CRM в скрипты, подумали мы. Изучили несколько API других CRM, особенно бесплатной встроенной в некоторые АТС - ShugarCRM и Vtiger, и да! можно, принцип тот же. Но это уже другая история, которую потом будем заливать на гитхаб отдельно.

Ссылки

Дисклеймер: любые совпадения с реальность вымышлены и это был не я,

Подробнее..

Из песочницы Только неБитрикс!. Почему не стоит игнорировать изучение этого фреймворка

30.08.2020 16:23:02 | Автор: admin
image

Часто отпрограммистов PHP можно услышать: Онет! Только неБитрикс!. Многие специалисты нехотят связываться фреймворком, считают его некрасивым инеудобным. Однако вакансий битрикс-разработчиков скаждым годом становится все больше. Уже сейчас программисты, которые работают сБитриксом, одни изсамых востребованных среди специалистов PHP.

Когда-то ябыл разработчиком1С, аувлечение PHP помогло мне вырасти доруководителя подразделения веб-разработки вNeti. Я постараюсь объяснить, почему программистам полезно изучить фреймворк Bitrix.

Как япознакомился сБитриксом


Три года назад мне предложили развивать направление веб-разработки. Ясогласился, потому что уменя был опыт создания высоконагруженных web-систем.

Первомуже клиенту, который кнам обратился, требовался битрикс-разработчик. Заказчику нужно было собрать государственный сервис для поддержки малого бизнеса. Клиент искал профессионала, который разрабатывает для Битрикса, знает объектно-ориентированное программирование иумеет писать сложные запросы.

Унас еще небыло битрикс-разработчиков, поэтому заказчик решил пойти подругому пути инанять веб-программиста, чтобы онуже напроекте изучил Битрикс. Явзялся зазадачу, где ипознакомился сфреймворком. Доэтого янеработал сБитриксом ичеткого мнения осистеме уменя небыло, хотя ячитал много негативных отзывов онем.

Разобравшись, японял, что этот фреймворк нивчем непроигрывает другим для таких задач.

Через полгода япокинул проект, чтобы полностью посвятить себя развитию подразделения. Уже два года ясам собеседую инабираю битрикс-разработчиков. Они востребованнее специалистов, которые работают сдругими фреймворками, восьми издесяти нашим клиентов нужны именно битрикс-разработчики.

image
Востребованность программистов PHP. Данные на 26 августа 2020 года. Источник: hh.ru.

Но, несмотря напотребности рынка, программисты PHP нехотят связываться сБитриксом. Одни работали сним поверхностно инеразобрались вего возможностях, другие несталкивались ссистемой вообще, ноотносятся кней плохо из-за негативных статей или отрицательных отзывов. Около30% кандидатов, скоторыми связывается наш HR-менеджер, отказываются отсобеседования, когда узнают, что нужно писать для Битрикса. Гораздо больше потенциальных сотрудников отсеиваются еще раньше, когда указывают врезюме, что неготовы работать сфреймворком.

Яхочу объяснить программистам PHP, почему стоит обратить внимание наБитрикс. Но, чтобы небыть голословным, сначала расскажу, почему клиенты выбирают эту систему ичем продукты фирмы 1С-Битрикс привлекают бизнес основного потребителя услуг программирования.

Почему клиенты выбирают Битрикс


Основные клиенты фирмы 1С-Битрикс владельцы интернет-магазинов и собственники бизнеса. Они выбирают продукты компании потому, что это коробочные решения с большим количеством функций, которые легко ставятся и запускаются с минимальными требованиями.

Интернет-магазины


Клиент, который купит иустановит 1СБитрикс: Управление сайтом влицензии Малый бизнес или выше, сразу получит:

  • Встроенную интеграцию почти совсеми российскими службами доставки, будьто Boxberry или Деловые линии. Чтобы выбрать службу доставки, ненадо ничего дополнительно подключать. Достаточно поставить галочку напротив нужного оператора.
  • Работающие понашему законодательству системы онлайн-оплаты (Яндекс-касса, Сбербанк-онлайн).
  • Встроенную синхронизацию с1С: Управление торговлей, 1С: Бухгалтерия, 1С: Зарплата иуправление персоналом.

Вбольшинстве зарубежных систем для создания интернет-магазинов нет полного комплекта синхронизаций: например, вних может быть интеграция снашими службами доставки, ноотсутствуют привычные онлайн-кассы. Такой функционал несложно подключить, нонеобходимо найти программиста, дать ему задание, дождаться, пока онего выполнит. Для предпринимателей это лишние действия, накоторые нужны время иденьги. Проще идешевле выбрать Битрикс, вкотором уже все есть.

image
В рейтинге CRM по реальным установкам на сайтах за сентябрь 2019 года, составленном компанией iTrack, 1С-Битрикс занимает первое место среди коммерческих CRM

Корпоративные сайты


Большинство решений нарынке узкоспециализированные: только CRM или только инструмент для управления проектами. Битрикс24, корпоративный сайт, объединяет всебе большое количество функционала. Это онлайн-офис ссистемой управления продажами, настроенными бизнес-процессами, чатом, лентой новостей. ВБитрикс24 можно вести учет рабочего времени, управлять проектами, ставить задачи сотрудникам.

Чтобы собрать нечто похожее самостоятельно, клиенту придется купить много отдельных сервисов иобъединитьих. Это затратно повремени иденьгам быстрее идешевле поставить коробку Битрикс24. Обилие функций водном месте подкупает: компании смотрят напродукт синтересом имногие нанего переходят.

Потребители видят, что запустить интернет-магазин или корпоративный портал, интегрированный синформационной системой предприятия, наБитриксе легко инедорого. Сделать тоже самое наOpenCart или WordPress дольше идороже. Разрабатывать подобное решение нафреймворках Laravel, Symfony или Yii2 более трудозатратно.

Решения для государственных организаций


Спродуктами 1С-Битрикс работают государственные, муниципальные, бюджетные организации. С1января 2016 года госучреждения обязаны использовать российское программное обеспечение, входящее вединый реестр. Решения 1С-Битрикс есть вэтом перечне.

Зачем нужны битрикс-разработчики


Теперь, когда понятно, почему потребители выбирают Битрикс, разберемся, зачем нужны разработчики. У80% клиентов коробка запускается быстро ипросто, иимхватает типового функционала. Такие заказчики ищут специалистов, чтобы поддерживать систему. Битрикс большое исложноеПО, и, как влюбом сложном механизме, внем встречаются ошибки ибаги. Это нормально.

Оставшимся20% клиентов чаще всего крупным компаниям недостаточно базовых возможностей коробки. Они дорабатывают систему под свои бизнес-процессы или пишут решения снуля, используя Битрикс как фреймворк.

Какие доработки чаще всего требуются заказчикам:

  • Добавить функционал. Например, насайты для медицинских центров добавляют функционал онлайн-записи наприем, историю обращений икарточку пациента. Этих возможностей нет вкоробке.
  • Настроить интеграцию. Часто клиентам нужна интеграция Битрикса сдругими системами. Например, заказчики хотят, чтобы сотрудник вличном кабинете видел зарплату, остатки отпусков идругую информацию, которую дает отдел кадров. Изначально этих возможностей нет вБитриксе и, чтобы все работало, требуется программист.
  • Исправить серверную часть. Некоторым клиентам ненравится серверная часть коробки: имкажется, что внутренние механизмы системы работают медленно. Таким заказчикам нужны оптимизация ирефакторинг кода.

Для доработки иподдержки системы клиенты Битрикса ищут программистов, которые работают сфреймворком. Нотаких специалистов мало.

За что программисты не любят Битрикс


Программисты PHP нехотят связываться сБитриксом считают его неинтересным, слишком сложным, тяжелым, неизящным ипереоцененным. Гораздо проще найти разработчика Laravel, Symfony или Yii2.

Намой взгляд, пренебрежение кБитриксу упрограммистов PHP появилось потрем причинам.

Плохо представлена документация. Вофреймворке много функционала, который неописан, и, чтобы понять, как онработает, надо лезть вкод.

Быть только программистом недостаточно. Коробка содержит много механизмов, которые необходимо знать нетолько вкачестве программиста, ноивкачестве аналитика-консультанта.

Например, вБитрикс24 запросы клиентов часто решаются непрограммированием, аобычной настройкой. Допустим, клиент хочет, чтобы после завершения задачи стартовал еще один бизнес-процесс. Тут ненадо писать код нужно лезть внастройки. Это, скорее, задача для консультанта, анедля программиста. Ноконсультантов Битрикс сейчас еще меньше, чем разработчиков, поэтому сэтими вопросами заказчики идут кпрограммистам, которые незнают, что ответить.

Обе проблемы временные исвязаны стем, что Битрикс только развивается ирынок еще неустоялся. Постепенно документацию исправят ипроизойдет четкое разделение наконсультантов ипрограммистов.

Битрикс восновном известен как CMS. Большинство разработчиков знают Битрикс как CMS для создания сайтов-визиток.80% программистов использовали только базовые функции иникогда непогружались внутрь, непытались изучать систему иядро фреймворка: ORM, Highload-блоки, мастера, визарды. Пощупали Битрикс снаружи непонравилось, аразвернуть непопытались. Это как попробовать съесть мандарин вкожуре.

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

Становление Битрикса похоже настановление 1С


То, что происходит сейчас сБитриксом, напоминает мне становление 1С. Когда 1Столько появился, среди программистов существовало мнение, что это неязык программирования, аерунда. Над специалистами, которые осваивали1С, смеялись. Имговорили, что писать нарусском фи ичто скоро фирма 1С загнется.

Ноэтого непроизошло. Укомпании настолько сильный маркетинговый штат, что 1С завоевала рынок. Сначала она заинтересовала предприятия малого исреднего бизнеса, апрограммные продукты набазе восьмого ядра привели фирме 1С крупных клиентов. Сейчас 1С: Предприятие используют 1500000организаций.

Разработчики, которые стояли натом, что программировать на1Снизко инеинтересно, оказались неправы. Нельзя сказать, что они остались неудел. Они все равно востребованы, нонамного меньше. Большинство специалистов все-таки пришло ктому, что надо перепрофилироваться на1С.

Тоже самое происходит сБитриксом. Скаждым годом Битрикс все популярнее уклиентов, нобольшинство программистов PHP нехочет сним работать, хотя это перспективное ивысокооплачиваемое направление.

Перспективы Битрикса


Битрикс-разработчики, которые занимаются программированием больших порталов и сложных личных кабинетов, очень востребованы и высокооплачиваемы. В зависимости от региона они зарабатывают от 30 000 (джуниоры) до 200 000 (сеньоры). Конечно, когда появится больше программистов и ниша заполнится, общий уровень заработка немного упадет. Но специалисты в этой сфере, скорее всего, будут востребованы всегда.

Специалисты, которые работают с Laravel, Symfony или любым другим MVC фреймворком PHP, останутся востребованными. У этих решений большая доля рынка, но достаточно специфические задачи.

Я считаю, через несколько лет Битрикс заберет 8090% рынка, потому что он в первую очередь ориентирован на бизнес. Если посмотреть красочные фото или видео конференций, посвященных Битриксу, становится ясно, как на них реагируют владельцы предприятий.

image
Конференция BitrixPower, прошедшая 4 октября 2019 года в Москве. Источник: группа 1С-Битрикс во ВКонтакте

Судя по динамике последних лет, доли продуктов 1С-Битрикс продолжат расти. Через несколько лет программистам PHP, чтобы быстро найти высокооплачиваемую работу, пригодится знание Битрикса наравне с другими фреймворками. И, возможно, при выборе между несколькими кандидатами именно знание Битрикса станет решающим аргументом в пользу одного из них.
Подробнее..

Заметки по API Aliexpress. Экспорт заказов в Bitrix24, RetailCRM, amoCRM

20.04.2021 14:21:11 | Автор: admin

Хочу поделиться опытом автоматизации экспорта заказов из Aliexpress в несколько. Приведенные примеры написаны на PHP, но библиотеки для работы с Aliexpress есть и для других языков. Структура запросов и ответов аналогична. Если перед вами стоит задача интеграции Aliexpress, надеюсь, эта статья будет вам полезна.

Итак, предположим, что у вас уже есть магазин на Aliexpress. И вы выбрали пункт меню Разработчикам. На момент публикации наблюдались сбои в локализации консоли разработчика, возможно, они будут исправлены в будущем, но если в консоли не отображаются уже созданные приложения или вход в консоль из кабинета продавца не срабатывает, есть пара советов:

  1. Заходите по ссылке https://seller.aliexpress.ru/login?return_url=https%3A%2F%2Fseller.aliexpress.ru Это исправит глюк с редирекстом на китайскую версию консоли, в которой создать приложение не возможно

  2. Перед входом, разлогиньтесь из под покупателя. Хотя вход будет произведен отдельно, консоль каким-то образом, может оказаться пустой. Т.е. вы войдете не под тем логином, под которым ожидали. Тот же глюк может быть позже, когда доступ для приложения может быть запрещён с ошибкой main account not auth subAccount

В консоли можно скачать SDK для разных языков и создать приложение. В результате у вас в распоряжении окажутся два из 3-х нужных для работы значения - App Key и App Secret. С третьим значением access_token все немного сложнее. Тут необходимо небольшое пояснение. В терминах консоли значения называются App Key, App Secret и access_token, а в терминах SDK, по крайней мере PHP-версии, эти же pачения называются appkey, secretKey и sessionKey. Ключ сессии, он же access_token можно получить двумя способами:

  1. Применив редирект обратно на свой сервер. Т.е. вы пишите приложение для менеджера, который по мере необходимости импортирует заказы из Aliexpress в CRM. Каждый раз он будет переходить из приложения на сайт Aliexpress, нажимать кнопку предоставления полномочий и возвращаться в приложение. При возврате буте получен параметр code, который с помощью curl вызова на https://oauth.aliexpress.com/token можно будет обменять на access_token

  2. Парсинг страницы после перехода по ссылке https://oauth.aliexpress.com/authorize. Ну или однократный вызов с ручным копированием access_token

Оба метода подробно описаны в документации. Там же упомянуто, что срок жизни access_token 1 год. Но не тут то было. Приложение созданное в консоли остается в стадии testing. А для нее срок жизни - 1 сутки. Чтобы опубликовать приложение, нужно отсканировать паспорт через приложение AliPay (российский загранпаспорт подошел). Но и это вам не поможет, т.к. следующий шаг введение номера кредитной карты и телефона, которые, видимо, должны быть выданы в Китае, т.к. ни то ни другое ввести не удается. Обращение в техподдержу Aliexpress в марте 2020 год осталось без ответа.

Надеюсь в будущем локализация будет доведена до конца и публикация для россиян станет доступна. Таким образом для дальнейшей работы подходит первый способ с нажатием кнопки каждый раз при импорте заказов, но передо мной была поставлена задача - сделать автоматический импорт без участия менеджера.

Я упомяну парсинг с помощью Selenium в конце стать, т.к. проблема с жизнью access_token может перед вами не стоять или решиться исправлением международного механизма публикации приложения.

Думаю, стоит начать с импорта справочника товаров Ailexpress в промежуточную таблица, чтоб присвоить им идентификаторы из CRM.

include "TopSdk.php";date_default_timezone_set('Asia/Shanghai'); $c = new TopClient;$c->appkey = 'xxxxxxxxxxx';$c->secretKey = 'xxxxxxxxxxxxxxxxxxxxxxxxxx';$sessionKey = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';$i = 1;$req = new AliexpressSolutionProductListGetRequest;$aeop_a_e_product_list_query = new ItemListQuery;$aeop_a_e_product_list_query->current_page=$i;$aeop_a_e_product_list_query->product_status_type="onSelling";$req->setAeopAEProductListQuery(json_encode($aeop_a_e_product_list_query));$rez = $c->execute($req, $sessionKey);var_dump($rez);

Получаем в $rez список товаров. Обратите внимание на счетчик $i. При первом запросе он будет равен 1, затем его нужно увеличивать, пока он не достигнет $rez->result->total_page и получать следующие страницы с товарами. Предлагаю вам ознакомиться с выводом скрипта. Первое что бросается в глаза машинный перевод названий товаров на английский язык. Это можно исправить на следующем шаге. Или сориентироваться по ссылкам на фотографию. А если товаров не много и перевод однозначный, то английские названия вас тоже могут устроить. Выведем эти названия и id (если ответ на запрос разбивается на несколько страниц, роцедуру нужно повторить для каждой из них)

foreach($rez->result->aeop_a_e_product_display_d_t_o_list->item_display_dto as $item){      echo $item->product_id."\t".$category->subject."\n";}

Если по каждой позиции предусмотрен выбор вариантов (размер, комплектация и т.д.), то нужно для каждого id вызвать метод, возвращающий эти варианты. Этим же методом можно получить оригинальное название товара на русском языке.

$req = new AliexpressSolutionProductInfoGetRequest;$req->setProductId($id);$rez = $c->execute($req, $sessionKey);var_dump ($rez);

В выводе содержится, много полезной информации, мы возьмём только идентификатоы и строки характеристик.

foreach($rez->result->aeop_ae_product_s_k_us->global_aeop_ae_product_sku as $sku){      echo $sku ->id."\t".$sku ->sku_code."\n";}

На этом этапе я столкнулся небольшой проблемой. Надписи в категориях товаров, которые видит покупатель, не возвращаются через API и доступны только через личный кабинет. Я имею ввиду, надписи, которые появляются при наведении на картинку с подвидом товара или надписи, которые сами определяют подвид.

На скриншоте пример с обувью. В карточке товара покупатель видит размер, а в заказ падает часть строки характеристик, по этой части можно понять какой именно Product code выбран. Обычно это штрих код товара. Я предполагаю, что те, кто заводят товар в личном кабинете продавца, ведут учет подкатегорий товара и их соответствие Product code. Я сделал первую сверку товаров и написал несколько простых страничек для пополнения и редактирования таблицы. Осталось получить список заказов и загрузить их в CRM.

$req = new AliexpressSolutionOrderGetRequest;$param0 = new OrderQuery;$param0->create_date_end="2221-12-31 12:12:12";$param0->create_date_start="2021-03-30 12:12:12";$param0->order_status_list = array("PLACE_ORDER_SUCCESS","IN_CANCEL","WAIT_SELLER_SEND_GOODS","SELLER_PART_SEND_GOODS","WAIT_BUYER_ACCEPT_GOODS","FUND_PROCESSING","IN_ISSUE","IN_FROZEN","WAIT_SELLER_EXAMINE_MONEY","RISK_CONTROL", "FINISH");$param0->current_page=$i;$req->setParam0(json_encode($param0));$rez = $c->execute($req, $sessionKey);

Ответ, так же как и в случаях со справочником товаров, разбивается на страницы. Обратите внимание на order_status_list. Он описан документации, которую я упоминал. Насколько я понял, список в моем коде является полным, что может пригодиться, если вы захотите экспортировать заказы во всех статусах.

Информацию по каждому новому заказу нужно получать отдельно. Строки идентифицирующие покупателей как RU shopper и т.п., довольно бесполезны, поэтому полное имя лучше брать из блока доставки. Примерно половина покупателей пишет свои контакты транслитом и не полностью, однако в нашем распоряжении есть номер телефона. По нему можно найти покупателя в накопленной, до начала работы с Aliexpress, базе и привязать соответствующий заказ.

При следующем получении списка заказов, можно проверить оплату неоплаченных заказов. В таблице загруженных ранее заказов таких записей может быть много, но Aliexpress заказы которые долго были не оплачены, через какое-то время перестает отображать в консоли в статусе ожидает оплаты. Думаю это связано с фиксацией цены. Менеджер, работающий около года с Aliexpress, сказал что стоит проверять заказы, которым не более 20 дней.

$req = new AliexpressSolutionOrderInfoGetRequest;$param1 = new OrderDetailQuery;$param1->ext_info_bit_flag="11111";$param1->order_id=$order;$req->setParam1(json_encode($param1));$rez = $c->execute($req, $sessionKey);$n = str_replace("'","''",$rez->result->data->receipt_address->contact_person); // мягкий знак в ФИО$p = $rez->result->data->receipt_address->phone_country . $rez->result->data->receipt_address->mobile_no;//$p = normalize_phone($p) // здесь могут быть варианты с лишней восьмёркой и т.д.$zi = $rez->result->data->receipt_address->zip;$gor = $rez->result->data->receipt_address->city;$pro = $rez->result->data->receipt_address->province;$adr = $rez->result->data->receipt_address->detail_address;if(isset ($rez->result->data->receipt_address->address2)) $adr .=$rez->result->data->receipt_address->address2;foreach($rez->result->data->child_order_ext_info_list->global_aeop_tp_order_product_info_dto as $item){    $pid = $item->product_id;    $j=json_decode($item->sku);    $s = "";    if(isset ($j->sku[0])) {        $s = $j->sku[0]->pValueId;    }    $cn =$category->quantity;    $pr =$item->unit_price->amount ;    echo $pid."\t". $s." \t " .$cn ." \t ".$pr."\n";}

Этот запрос возвращает данные и о скидке, если вы проводите в вашем магазине на Aliexpress промоакцию.

В заключении, хочу привести еще несколько фрагментов кода. По одному для каждой CRM с которыми мне доводилось работать. Я делаю это, чтобы вся информация по интеграции была в одном месте. Детальные разборы добавления заказов ищутся проще, чем информация по Aliexpress, но если кому-то нужно будет быстро сделать интеграцию, можно взять эти наработки.

Я взял из их своих проектов и отвязал от интеграций (в том числе Алиэкспресса). Каждый пример создает контакт, затем лид/сделку, привязывает к ней контакт и добавляет один товар. Я с удовольствием помогу вам c интеграцией за небольшую плату, если вы решите начать продажи на Алиэкспресс. Тем более что приближается пора отпусков и дополнительные деньги не помешают ни мне, не вам. Почта для связи tlx {cобака} list.ru. Есть большой опыт по интеграции фулфилментов, телефонии и прочего API c различными CRM и общий навык автоматизации.

amoCRM
$subdomain = "xxxxxxxxx";function amo_call($access_token, $link, $data) {$headers = ['Authorization: Bearer ' . $access_token];$curl = curl_init(); //Сохраняем дескриптор сеанса cURLcurl_setopt($curl,CURLOPT_RETURNTRANSFER, true);curl_setopt($curl,CURLOPT_USERAGENT,'amoCRM-oAuth-client/1.0');curl_setopt($curl,CURLOPT_URL, $link);curl_setopt($curl,CURLOPT_CUSTOMREQUEST,'POST');curl_setopt($curl,CURLOPT_POSTFIELDS,json_encode($data));curl_setopt($curl,CURLOPT_HTTPHEADER, $headers);curl_setopt($curl,CURLOPT_HEADER, false);curl_setopt($curl,CURLOPT_SSL_VERIFYPEER, 1);curl_setopt($curl,CURLOPT_SSL_VERIFYHOST, 2);$out = curl_exec($curl); //Инициируем запрос к API и сохраняем ответ в переменную$code = curl_getinfo($curl, CURLINFO_HTTP_CODE);curl_close($curl);$code = (int)$code;$errors = [400 => 'Bad request',401 => 'Unauthorized',403 => 'Forbidden',404 => 'Not found',500 => 'Internal server error',502 => 'Bad gateway',503 => 'Service unavailable',];try{if ($code < 200 || $code > 204) {return  -1;}}catch(\Exception $e){return  -1;}$response = json_decode($out, true);return  $response;}/* //Это упрощенный способ получения $access_token. Подробнее о получении, вермени жизни и обновлении, см. документацию $link = 'https://' . $subdomain . '.amocrm.ru/oauth2/access_token'; //Формируем URL для запроса$data = ['client_id' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx','client_secret' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx','grant_type' => 'authorization_code','code' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx','redirect_uri' => 'http://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,];$curl = curl_init(); //Сохраняем дескриптор сеанса cURLcurl_setopt($curl,CURLOPT_RETURNTRANSFER, true);curl_setopt($curl,CURLOPT_USERAGENT,'amoCRM-oAuth-client/1.0');curl_setopt($curl,CURLOPT_URL, $link);curl_setopt($curl,CURLOPT_HTTPHEADER,['Content-Type:application/json']);curl_setopt($curl,CURLOPT_HEADER, false);curl_setopt($curl,CURLOPT_CUSTOMREQUEST, 'POST');curl_setopt($curl,CURLOPT_POSTFIELDS, json_encode($data));curl_setopt($curl,CURLOPT_SSL_VERIFYPEER, 1);curl_setopt($curl,CURLOPT_SSL_VERIFYHOST, 2);$out = curl_exec($curl); //Инициируем запрос к API и сохраняем ответ в переменную$code = curl_getinfo($curl, CURLINFO_HTTP_CODE);curl_close($curl);$code = (int)$code;$errors = [400 => 'Bad request',401 => 'Unauthorized',403 => 'Forbidden',404 => 'Not found',500 => 'Internal server error',502 => 'Bad gateway',503 => 'Service unavailable',];try{if ($code < 200 || $code > 204) {throw new Exception(isset($errors[$code]) ? $errors[$code] : 'Undefined error', $code);}}catch(\Exception $e){die("Ошибка: ' . $e->getMessage() . PHP_EOL . 'Код ошибки: ' . $e->getCode());}$response = json_decode($out, true);var_dump($response);$access_token = $response['access_token']; //Access токен$refresh_token = $response['refresh_token']; //Refresh токен$token_type = $response['token_type']; //Тип токена$expires_in = $response['expires_in']; //Через сколько действие токена истекает*/$access_token ="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";// создаем контакт. В рабочей версии лучше перед этим поискать контакт по номеру телефона. Методом /api/v4/contacts  с параметром filter[custom_fields_values]//тестовые данные$p ="+79000000000";$n= "Петр Петров";$qnt = 1;$ord = "xxxxxxxxxxxxxxxxx";$link='https://'.$subdomain.'.amocrm.ru/api/v2/contacts';$data = array ('add' =>array (0 =>array ('name' => $n,'custom_fields'=>array(array('id' => '953127','values' => array(array("value"=>$p,"enum"=> "MOB"),),),),) ,) ,  ) ;$response = amo_call($access_token, $link, $data);if ($response==-1) {die("что-то пошло не так при добавлении контакта /n");} else {var_dump($response);$cid = $response["_embedded"]["items"][0]["id"];// создаем сделку с привязкой к найденному или созданному контакту$pipeline_id = '4188580';$lead_status_id = '39384853';$lead_name  ="Заказ из Aliexpress  " . $ord;$link='https://'.$subdomain.'.amocrm.ru/api/v2/leads';$data = array ('add' =>  array (0 =>array ('name' => $lead_name,'status_id' => $lead_status_id, //id статуса'pipeline_id' => $pipeline_id,'contacts_id'=>  array ($cid ),), ),);$response = amo_call($access_token, $link, $data);if ($response==-1) {die("что-то пошло не так при добавлении сделки /n");} else {$did = $response["_embedded"]["items"][0]["id"];var_dump($response);// добавляем товары в сделку$link='https://'.$subdomain.'.amocrm.ru/api/v4/leads/'.$did.'/link';$data = array (0 =>array ('to_entity_id' => 327219, //id товара можно посмореть методами api или в html коде страницы товара (не путать с артикулом)'to_entity_type' =>'catalog_elements','metadata' => array("quantity" =>  $qnt,"catalog_id" =>  5321 // id каталога, виден в адресной строке при входе в каталог),),);$response = amo_call($access_token, $link, $data);if ($response==-1) {die("что-то пошло не так при добавлении товаров в сделку /n");} else {var_dump($response);//сообщить об успешно выполнной операции}}
Bitrix24
function b24_call($queryUrl, $queryData) {$curl = curl_init();curl_setopt_array($curl, array(CURLOPT_SSL_VERIFYPEER => 0,CURLOPT_POST => 1,CURLOPT_HEADER => 0,CURLOPT_RETURNTRANSFER => 1,CURLOPT_URL => $queryUrl,CURLOPT_POSTFIELDS => $queryData,));$out =  curl_exec($curl);$code = curl_getinfo($curl, CURLINFO_HTTP_CODE);if ($code < 200 || $code > 204) {return  -1;}curl_close($curl);$response = json_decode($out, true);return  $response;}$p ="+79000000000";$n= "Петр Петров";$zi = "111111";$pro = "Ньюйорская область";$gor = "Ньюджерси";$adr  = "ул. Линкольна дом 1";$qnt = 1;$ord = "xxxxxxxxxxxxxxxxx";//Перед созданием контакта лучше поискать его методом crm.contact.list с параметром array('filter' => array('PHONE' => $ph))$queryUrl  = 'https://xxxxxxxxxx.ru/rest/48/xxxxxxxxxxxxxxxxx/crm.contact.add.json';$queryData = http_build_query(array('fields' => array("NAME"=> $n, "PHONE"  => array(array('VALUE' =>$p, 'VALUE_TYPE' => 'MOBILE')),),'params' => array("REGISTER_SONET_EVENT" => "N")));$response= b24_call($queryUrl, $queryData);    if ($response==-1) {die("что-то пошло не так при добавлении контакта /n");} else {var_dump($response);$cid = $response["result"];echo "!".$cid."!\n";$queryUrl  = 'https://xxxxxxxxxx.ru/rest/48/xxxxxxxxxxxxxxxxx/crm.requisite.add.json';$queryData = http_build_query(array('fields'=> array("PRESET_ID"=> 3,"ENTITY_TYPE_ID"=> 3,"ENTITY_ID"=> $cid,"NAME"=>"Реквизит","ACTIVE"=>"Y","SORT"=>100)));$response= b24_call($queryUrl, $queryData);if ($response==-1) {die("что-то пошло не так при добавлении реквизита /n");} else {var_dump($response);$rid = $response["result"];$queryUrl  = 'https://xxxxxxxxxx.ru/rest/48/xxxxxxxxxxxxxxxxx/crm.address.add.json';$queryData = http_build_query(array('fields'=> array("TYPE_ID"=> 1,"ENTITY_TYPE_ID"=> 8,"ENTITY_ID"=> $rid,"POSTAL_CODE"=> "$zi", "PROVINCE"=> "$pro","CITY"=> "$gor","ADDRESS_1"=> "$adr","COUNTRY"=>  "Россия")));$response= b24_call($queryUrl, $queryData);if ($response==-1) {die("что-то пошло не так при добавлении адреса в реквизит /n");} else {var_dump($response);$lead_name = "Заказ из Aliexpress  " . $ord;$queryUrl  = 'https://xxxxxxxxxx.ru/rest/48/xxxxxxxxxxxxxxxxx/crm.lead.add.json';$queryData = http_build_query(array('fields' => array("TITLE" => $lead_name,"TYPE_ID" => "GOODS","STAGE_ID" => "NEW","CONTACT_ID"=> $cid,"CURRENCY_ID"=>  "RUB",),'params' => array("REGISTER_SONET_EVENT" => "Y")));$response= b24_call($queryUrl, $queryData);if ($response==-1) {die("что-то пошло не так при добавлении сделки /n");} else {var_dump($response);$did = $response["result"];$items = array();$items[] =  array('PRODUCT_ID' => "2968", 'PRICE' => "1.00", 'QUANTITY' => $qnt);$queryUrl  = 'https://xxxxxxxxxx.ru/rest/48/xxxxxxxxxxxxxxxxx/crm.lead.productrows.set.json';$queryData = http_build_query(array("id" => $did,"rows"=>$items));$response= b24_call($queryUrl, $queryData);if ($response==-1) {die("что-то пошло не так при добавлении товаров в сделку /n");} else {var_dump($response);//сообщить об успешно выполнной операции}}}}}
RetailCRM
$crmKey = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';function retail_call($url, $postData) {$curl = curl_init();curl_setopt($curl, CURLOPT_URL, $url);curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);curl_setopt($curl, CURLOPT_FAILONERROR, false);curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);curl_setopt($curl, CURLOPT_TIMEOUT, 30);curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30);curl_setopt($curl, CURLOPT_POST, true);curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);            $out =  curl_exec($curl);$code = curl_getinfo($curl, CURLINFO_HTTP_CODE);if ($code < 200 || $code > 204) {return  -1;}curl_close($curl);$response = json_decode($out, true);return  $response;}$p ="+79000000000";$n= "Петр Петров";$zi = "111111";$pro = "Ньюйорская область";$gor = "Ньюджерси";$adr  = "ул. Линкольна дом 1";$qnt = 1;$ord = "xxxxxxxxxxxxxxxxx";$url  = 'https://xxxxxxxxxx..ru/api/v5/customers/create';$postData = array('site' =>'xxxxxxxxxx.ru','customer' => json_encode(array('firstName' =>$n,)),'apiKey' => $crmKey,);$rez = retail_call($url, $postData);var_dump($rez);$cid = $rez["id"];$url  = 'https://xxxxxxxxxx.ru/api/v5/orders/create';$postData = array('site' =>'xxxxxxxxxx.ru','order' => json_encode(array('customer'=> array('id' => $cid,),    'items' => array(array('quantity' => 6,'offer'=> array('externalId' => 'xxxxxxxxxxx',)),))),'apiKey' => $crmKey,);$rez = retail_call($url, $postData);var_dump($rez);echo "\n".$rez["id"]."\n";
Selenium (для получения access_token)
from selenium import webdriverfrom time import sleepbrowser = webdriver.Firefox()browser.get("https://seller.aliexpress.ru/")sleep(5)browser.switch_to.frame(browser.find_element_by_css_selector("iframe.iframe-with-loader_iframe__QQc_0"))e = browser.find_element_by_id("fm-login-id")e.send_keys("xxxxxx@xxxxxxxx.ru")e = browser.find_element_by_id("fm-login-password")e.send_keys("xxxxxxxxxxxxx")e = browser.find_element_by_id("fm-login-submit")e.click()sleep(15)browser.get("https://oauth.aliexpress.com/authorize?&response_type=token&client_id=XXXXXXXX&state=1212&view=web&sp=ae")sleep(5)try:    e = driver.find_element_by_id("sub")    e.click()except Exception:    print('Session login')sleep(5)txt = "-1"try:    e = driver.find_element_by_id("wrap")    print(e.get_attribute('innerHTML'))    txt = e.get_attribute('innerHTML')except Exception:    print('Session login')x = txt.split("access_token: ")y = x[1].split("<br>")print y[0]
Подробнее..
Категории: Php , Api , Crm-системы , Amocrm , Bitrix24 , Aliexpress , Retailcrm

Выгрузка пользователей из 1C ЗУП в Битрикс24 или правдивая история о том как настроить интеграцию 1С-Битрикс24 c 1С ЗУП

10.02.2021 00:11:55 | Автор: admin

В жизни так бывает, причём бывает чаще чем хотелось бы, хоть в целом и довольно редко надо интегрировать Битрикс24 с ЗУП. Сими дружественными компаниями заявлена штатная интеграция (но только для коробки Б24), которая осуществляется по следующей принципиальной схеме:

  1. Обмен инициирует всегда 1С. Это либо штатный, либо устанавливаемый самостоятельно и доступный модуль обмена, который посылает запросы.

  2. На стороне Б24 имеем в качестве точки обмена скрипт, если быть точнее скрипты (но об этом будет ниже), в одном из которых вызов метода IncludeComponent, который подключает контроллер. Он и таит в себе логику обмена.

Штатный обмен, в принципе, если быть экспертом одного из продуктов можно освоить за небольшое количество минут или часов информация представлена на одном из официальных сайтов 1С-Битрикс - https://1c.1c-bitrix.ru/intranet/employees.php.

Пролог

Нам же это скучно, поэтому ввязываемся в авантюру по интеграции ЗУП с Б24 Enterprise, а чтобы было интереснее берем закрытый объект, почти совсем не бизнес даже, а учреждение с многоуровневой и чудно ветвленой системой безопасности.

В общем, на руках бэкап Б24 с обезличенными данными и обезличенный же XML-файл обмена из ЗУП.

Итак, сама задача Хотя, нет. До самой задачи ещё далеко не помешало бы сначала наладить тестовый механизм для того, чтобы по заверениям работающий штатный алгоритм проверить.

Инструментарий:

  • Виртуальная машина VMBitrix 1 шт.

  • 1С-Битрикс24 (копия для разработки) 1 шт.

  • Файл обмена, выгруженный предположительно штатным модулем обмена 1С 1 шт.

  • VS Code + SSH FS плагин на будущее 1 комплект.

  • Postman 1 шт.

Виртуальная машина VMBitrix

По правде говоря, это никакая не виртуальная и даже не машина, а CentOS 7 (ну, или 6) со всеми вытекающими. Можно из чистой центоси сделать своеобразный и уже сконфигурированный LAMP+ для Битрикс несколькими командами.

wget http://repos.1c-bitrix.ru/yum/bitrix-env.sh

# chmod +x bitrix-env.sh

# ./bitrix-env.sh

Для дотошных читателей следует рассказать, что виртуальная машина в реальности всё же существует. На клиентском сайте вендора в разделе скачать. Образы уже сконфигурированных ОС под популярные виртуализации выложены и в корне сайта по умолчанию уже лежит скрипт установки демо и скрипт восстановления. Именно скрипт восстановления был использован для создания локальной копии портала.

Следует ещё отметить, что VMBitrix не единственное, но самое быстро-разворачиваемое универсальное окружение для Б24.

1С-Битрикс24 Enterprise

Не буду много распространяться про то, что отличает Энтерпрайз от других коробок. Наверное, в данном повествовании хватит акцента на цене и уровне ответственности. Тем более, модули связанные с масштабированием не используются. Впрочем, как и многосайтовость.

Файл обмена из 1С ЗУП

Если вы хоть раз занимались интеграцией двух систем, будучи ответственным только на одном продукте, то вам знакомо как велик соблазн спихнуть на ту сторону любую мелочь, которую лень проверять на своей стороне. Этот недуг поражает даже самых ответственных людей, выступающих в любой роли и с любым уровнем погружения. Поддавался недугу и я.

Попытка повлиять на то чтобы пришли нужные данные сами чудесным образом, догадавшись, куда и в какой последовательности записываться, для очистки совести тоже осуществлена.

VS Code + SSH FS плагин

Итак, вооружившись доступом к файловой системе проекта, мы начинаем свое путешествие в увлекательный мир не задокументированных интеграций.

Не зря в самом начале статьи была реплика про то, что Обмен инициирует всегда 1С. Для понимания архитектуры это был первый шаг, в модуле обмена на стороне 1С прописан адрес скрипта, выступающего узлом обмена в Б24 по умолчанию это /bitrix/admin/1c_intranet.php.

В нем, согласно правилам системы ничего не хранится. Подключается один из служебных скриптов системного модуля Интранет(intranet) /bitrix/modules/intranet/tools/1c_intranet.php.

Именно этот модуль нам дает программный интерфейс для организации работы с сотрудниками и структурой на портале. Модули в BitrixFramework занимают место модели в архитектуре MVC.

И именно для взаимодействия с ним написанный системный компонент intranet.users.import.1c вызывается из служебного скрипта при помощи метода IncludeComponent. Компоненты в BitrixFramework занимают место контроллера в архитектуре MVC. На вход компонента подается массив параметров, если не вдаваться в тонкости, то настройки из модуля Интранет, которые задаются в административной части корпортала.

Postman

При упоминании должности почтальона в наших широтах перед глазами встает образ скорее Печкина из Простоквашино, нежели герой Кевина Костнера из одноименного заокеанского фильма.

Но наш герой программа, адрес тоже известен https://www.postman.com/ .

Эпилог

Путем нехитрых манипуляций вычитки кода того самого системного компонента и экспериментов с программой-почтальоном за пару часов выработан полуавтоматических алгоритм, позволяющий подсунуть в Б24 файл выгрузки из 1С.

Что важно знать про обмен:

  • Протокол обмена GET

  • Нужно несколько последовательных запросов с разными параметрами

Если файл выгрузки 1С ЗУП в архиве, то нужно использовать галочку Использовать сжатие zip, если доступно в настройках модуля Интранет в админке. И наоборот если XML без архивной оболочки галочку нужно снять.

Первый запрос, авторизация по логину и паролю:

GET http://портал/bitrix/admin/1c_intranet.php?mode=checkauth

Возвращает PHPSESSID. Его необходимо в последующем передавать с каждым запросом.

Второй запрос:

GET http://портал/bitrix/admin/1c_intranet.php?mode=init

Подготавливает/вычищает папку для загрузки файла. Возвращает что-то вроде zip=no

file_limit=204800, если всё отработало.

Третий запрос:

GET http://портал /bitrix/admin/1c_intranet.php?mode=file&PHPSESSID=tmfi6bf67llse3akv7cv13m6h8&filename=import.xml

В случае успешной передачи и записи файла на сервер возвращает success. Будьте бдительны нужно передать в Body сам файл бинарно, и указать его название в GET-параметре filename.

Четвертый запрос:

GET http://портал /bitrix/admin/1c_intranet.php?mode=import&PHPSESSID=tmfi6bf67llse3akv7cv13m6h8&filename=import.xml

Надо отсылать несколько раз с теми же параметрами, пока не пройдут последовательно все шаги импорта. Все эти шаги также можно вычитать в коде вышеуказанного компонента, осуществляющего импорт. Возвращаемые значения:

progress

Временныетаблицыудалены.

progress

Временныетаблицысозданы.

progress

Файлимпортапрочитан.

progress

Временныетаблицыпроиндексированы.

progress

Проверкаструктурыуспешнопройдена.

progress

Метаданныеимпортированыуспешно.

progress

Обработано2из2пользователей.

progress

Загрузкапользователейзавершена.

progress

Обработано11из11записейграфикаотсутствий.

progress

Загрузкаграфикаотсутствийзавершена.

success

Импортуспешнозавершен.

Постскриптум

Наверняка, кто-то из комментаторов укажет на другие инструменты, или сможет поделиться похожим опытом. Возможно, кто-то проведет параллели с импортом каталога из УТ в БУС.

По правде говоря, сам тоже, хоть в статье и опустил, но руководствовался аналогичным опытом. Продолжение следует в следующей статье расскажу как решалась сама задача породившую такую хитроумную организацию труда.

Подробнее..

Recovery mode Выгрузка пользователей из 1C ЗУП в Битрикс24 или правдивая история о том как настроить интеграцию 1С-Битрикс24 c 1С ЗУП

10.02.2021 02:16:32 | Автор: admin

В жизни так бывает, причём бывает чаще чем хотелось бы, хоть в целом и довольно редко надо интегрировать Битрикс24 с ЗУП. Сими дружественными компаниями заявлена штатная интеграция (но только для коробки Б24), которая осуществляется по следующей принципиальной схеме:

  1. Обмен инициирует всегда 1С. Это либо штатный, либо устанавливаемый самостоятельно и доступный модуль обмена, который посылает запросы.

  2. На стороне Б24 имеем в качестве точки обмена скрипт, если быть точнее скрипты (но об этом будет ниже), в одном из которых вызов метода IncludeComponent, который подключает контроллер. Он и таит в себе логику обмена.

Штатный обмен, в принципе, если быть экспертом одного из продуктов можно освоить за небольшое количество минут или часов информация представлена на одном из официальных сайтов 1С-Битрикс.

Пролог

Нам же это скучно, поэтому ввязываемся в авантюру по интеграции ЗУП с Б24 Enterprise, а чтобы было интереснее берем закрытый объект, почти совсем не бизнес даже, а учреждение с многоуровневой и чудно ветвленой системой безопасности.

В общем, на руках бэкап Б24 с обезличенными данными и обезличенный же XML-файл обмена из ЗУП.

Итак, сама задача Хотя, нет. До самой задачи ещё далеко не помешало бы сначала наладить тестовый механизм для того, чтобы по заверениям работающий штатный алгоритм проверить.

Инструментарий:

  • Виртуальная машина VMBitrix 1 шт.

  • 1С-Битрикс24 (копия для разработки) 1 шт.

  • Файл обмена, выгруженный предположительно штатным модулем обмена 1С 1 шт.

  • VS Code + SSH FS плагин на будущее 1 комплект.

  • Postman 1 шт.

Виртуальная машина VMBitrix

По правде говоря, это никакая не виртуальная и даже не машина, а CentOS 7 (ну, или 6) со всеми вытекающими. Можно из чистой центоси сделать своеобразный и уже сконфигурированный LAMP+ для Битрикс несколькими командами.

wget http://repos.1c-bitrix.ru/yum/bitrix-env.sh

# chmod +x bitrix-env.sh

# ./bitrix-env.sh

Для дотошных читателей следует рассказать, что виртуальная машина в реальности всё же существует. На клиентском сайте вендора в разделе скачать. Образы уже сконфигурированных ОС под популярные виртуализации выложены и в корне сайта по умолчанию уже лежит скрипт установки демо и скрипт восстановления. Именно скрипт восстановления был использован для создания локальной копии портала.

Следует ещё отметить, что VMBitrix не единственное, но самое быстро-разворачиваемое универсальное окружение для Б24.

1С-Битрикс24 Enterprise

Не буду много распространяться про то, что отличает Энтерпрайз от других коробок. Наверное, в данном повествовании хватит акцента на цене и уровне ответственности. Тем более, модули связанные с масштабированием не используются. Впрочем, как и многосайтовость.

Файл обмена из 1С ЗУП

Если вы хоть раз занимались интеграцией двух систем, будучи ответственным только на одном продукте, то вам знакомо как велик соблазн спихнуть на ту сторону любую мелочь, которую лень проверять на своей стороне. Этот недуг поражает даже самых ответственных людей, выступающих в любой роли и с любым уровнем погружения. Поддавался недугу и я.

Попытка повлиять на то чтобы пришли нужные данные сами чудесным образом, догадавшись, куда и в какой последовательности записываться, для очистки совести тоже осуществлена.

VS Code + SSH FS плагин

Итак, вооружившись доступом к файловой системе проекта, мы начинаем свое путешествие в увлекательный мир не задокументированных интеграций.

Не зря в самом начале статьи была реплика про то, что Обмен инициирует всегда 1С. Для понимания архитектуры это был первый шаг, в модуле обмена на стороне 1С прописан адрес скрипта, выступающего узлом обмена в Б24 по умолчанию это /bitrix/admin/1c_intranet.php.

В нем, согласно правилам системы ничего не хранится. Подключается один из служебных скриптов системного модуля Интранет(intranet) /bitrix/modules/intranet/tools/1c_intranet.php.

Именно этот модуль нам дает программный интерфейс для организации работы с сотрудниками и структурой на портале. Модули в BitrixFramework занимают место модели в архитектуре MVC.

И именно для взаимодействия с ним написанный системный компонент intranet.users.import.1c вызывается из служебного скрипта при помощи метода IncludeComponent. Компоненты в BitrixFramework занимают место контроллера в архитектуре MVC. На вход компонента подается массив параметров, если не вдаваться в тонкости, то настройки из модуля Интранет, которые задаются в административной части корпортала.

Postman

При упоминании должности почтальона в наших широтах перед глазами встает образ скорее Печкина из Простоквашино, нежели герой Кевина Костнера из одноименного заокеанского фильма.

Но наш герой программа, адрес тоже известен: postman.com [ссылка удалена модератором].

Эпилог

Путем нехитрых манипуляций вычитки кода того самого системного компонента и экспериментов с программой-почтальоном за пару часов выработан полуавтоматических алгоритм, позволяющий подсунуть в Б24 файл выгрузки из 1С.

Что важно знать про обмен:

  • Протокол обмена GET

  • Нужно несколько последовательных запросов с разными параметрами

Если файл выгрузки 1С ЗУП в архиве, то нужно использовать галочку Использовать сжатие zip, если доступно в настройках модуля Интранет в админке. И наоборот если XML без архивной оболочки галочку нужно снять.

Первый запрос, авторизация по логину и паролю:

GET http://портал/bitrix/admin/1c_intranet.php?mode=checkauth

Возвращает PHPSESSID. Его необходимо в последующем передавать с каждым запросом.

Второй запрос:

GET http://портал/bitrix/admin/1c_intranet.php?mode=init

Подготавливает/вычищает папку для загрузки файла. Возвращает что-то вроде zip=no

file_limit=204800, если всё отработало.

Третий запрос:

GET http://портал /bitrix/admin/1c_intranet.php?mode=file&PHPSESSID=tmfi6bf67llse3akv7cv13m6h8&filename=import.xml

В случае успешной передачи и записи файла на сервер возвращает success. Будьте бдительны нужно передать в Body сам файл бинарно, и указать его название в GET-параметре filename.

Четвертый запрос:

GET http://портал /bitrix/admin/1c_intranet.php?mode=import&PHPSESSID=tmfi6bf67llse3akv7cv13m6h8&filename=import.xml

Надо отсылать несколько раз с теми же параметрами, пока не пройдут последовательно все шаги импорта. Все эти шаги также можно вычитать в коде вышеуказанного компонента, осуществляющего импорт. Возвращаемые значения:

progress

Временныетаблицыудалены.

progress

Временныетаблицысозданы.

progress

Файлимпортапрочитан.

progress

Временныетаблицыпроиндексированы.

progress

Проверкаструктурыуспешнопройдена.

progress

Метаданныеимпортированыуспешно.

progress

Обработано2из2пользователей.

progress

Загрузкапользователейзавершена.

progress

Обработано11из11записейграфикаотсутствий.

progress

Загрузкаграфикаотсутствийзавершена.

success

Импортуспешнозавершен.

Постскриптум

Наверняка, кто-то из комментаторов укажет на другие инструменты, или сможет поделиться похожим опытом. Возможно, кто-то проведет параллели с импортом каталога из УТ в БУС.

По правде говоря, сам тоже, хоть в статье и опустил, но руководствовался аналогичным опытом. Продолжение следует в следующей статье расскажу как решалась сама задача породившую такую хитроумную организацию труда.

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru