В понедельник, как вы вероятно знаете, был вебинар по разработке чатботов, на который мы приглашали всех партнеров - авторов решений для Маркетплейс и Приложений24. Спасибо всем тем, кто пришел послушать нас в онлайн, и, конечно, особая благодарность Антону Долганину за живую демонстрацию кода. Те, кто не смог посмотреть вебинар в онлайне, могут увидеть его запись:
Кроме записи я также рад поделиться с вами кодом Антона (архив captain.zip) и, как обещал, даю ссылку на рекомендуемый PHP SDK для Битрикс24 от Максима Месилова https://github.com/mesilov/bitrix24-php-sdk
Нет повода откладывать разработку чатботов, коллеги .
Недавно вышла в релиз новая E-commerce платформа 1С-Битрикс. Платформа привнесла множество улучшений и изменений, которые раскроются перед вами после перехода на новый компонент «Оформления заказов».
Во время написания статьи я, вместе с вами, переведу один из своих рабочих проектов на новый компонент «Оформления заказов».
Прежде чем мы приступим, хочется поблагодарить разработчика компании 1С-Битрикс Орландо Виласека за огромную работу, которую он провел, создавая новый компонент. Компонент написан с использованием ядра D7.
Во время создания компонента в компании, среди тестировщиков, появился даже мем:
«В компоненте Орландо мало багов» - я считаю это странно, видать плохо ищут.
Я конечно верю нашему отделу тестирования, но решил проверить сам, воодушевился высказыванием и решился перейти на новый компонент.
Коллеги, 11-го апреля состоится вебинар, на котором Антон Долганин с некоторой моей поддержкой расскажет про разработку чат-ботов для Битрикс24. Регистрироваться можно уже сейчас:
— Что такое боты, зачем они нужны? — Добавление приложения бота на ваш портал. — Базовые события бота. — Регистрация бота, приветствие сотрудников. — Простое и интерактивное общение с ботом (викторина). — Инициация диалога ботом. — Портирование на коробку.
Мы стараемся постоянно доделывать те или иные возможности в Маркетплейс и Приложениях24, но не всегда получается об этом вовремя рассказывать. Буду стараться исправить это положение вещей и начну с анонса двух небольших, но полезных мелочей, которые у нас давно просили партнеры.
Сортировка модулей
Прежде всего, это обещанная возможность управлять порядком вывода собственных модулей на странице автора Маркетплейс и в блоке "Другие решения". Теперь у каждого вашего модуля есть поле "Сортировка". Достаточно просто указать нужные вам значения (по умолчанию, 500), чтобы задать порядок сортировки. Второй критерий сортировки остается без изменений - решения ранжируются по "популярности".
Купоны на две недели и на месяц
Вторая важная доделка касается авторов, разрабатывающих решения для Битрикс24. Как вы знаете, для платного решения можно указать произвольный демо-период, который позволяет потенциальным покупателям ознакомиться с функционалом решения до покупки. И периодически возникает ситуация, когда пользователю не хватает этого периода по ряду причин, или во время тестирования обнаруживается ошибка, которая реально мешает продолжению тестирования. В этом случае партнеры хотели бы продлевать демо-период на некоторый небольшой срок, для чего они могли бы вручную выписать и передать пользователю купон. Однако до текущего момента, авторы могли выписать купон минимум на трехмесячный срок - это тот же период, который доступен покупателям в Приложениях24 для совершения покупки. Теперь же мы добавили возможность выписки купона на две недели и на 1 месяц. Эта возможность есть только в партнерском кабинете, конечные пользователи не смогут самостоятельно приобретать ваши решения на указанные периоды.
Управление заказами — важная часть жизни интернет-магазина. Мы проводим в разделе заказы большую часть рабочего времени, контролируя заказы, корректируя и отслеживая отгрузки и оплаты, изменяя статусы. Мы осознаем всю ответственность перед нашими клиентами, привнося новую систему управления заказами в наш продукт. Мы делаем революцию в управлении заказами в новой платформе 1С-Битрикс, создавая условия к 100% контролю за ходом выполнения заказа.
Очень жду от вас комментариев к статье, давайте совместно делать продукт удобным и эффективным в решение ваших задач!
Логика работы форм
Общие принципы логики работы новых форм сохраняют преемственность предыдущих.
В формах всегда присутствовало два состояния заказа:
Просмотр заказа - некий пульт управления на котором можно было сменить любой статус, проконтролировать ход работы по заказу, быстро посмотреть данные по клиенту, форма не предусматривала изменение самого заказа. В новой форме просмотра заказа мы расширили возможности, привнеся управления отгрузками и оплатами, на форме просмотра можно быстро создать, удалить или изменить данные в отгрузках и оплатах.
Редактирование заказа - где можно изменить сам заказ, в новых формах данная логика сохранилась и расширилась управлением скидками.
В предыдущих формах вы нас просили не изменять данные по суммам заказа и суммам товарных строк мгновенно, а давать возможность актуализировать данные по заказу по желанию менеджера. В новых формах мы реализовали данную возможно и в формах появилась кнопка "Пересчитать заказ" - которая пересчитывает заказ на текущий момент, актуализируя все скидки и изменения по товарам и ценам. В противном случае, формы хранят всю информацию по заказу в рамках заказа, что дает возможность обсуждать заказ с клиентом, видя его в первозданном состояние.
Поздравляю всех читателей статьи с выходом в релиз новой платформы 1С-Битрикс Управления Сайтами.
Переход на новую платформу это не просто установка новых обновлений, это серия действий которые необходимо выполнить, в этой статье мы разберем эти действия.
Установка обновлений – этап 1
Я взял стандартный интернет-магазин с дефолтным шаблоном поставляемым компанией 1С-Битрикс, взял специально не новый шаблон, который изначально предназначался для новой платформы, а предыдущий от 14,5 версии, проведем так сказать эксперимент, можно ли делать переход тем кто использует предыдущие решения от 1С-Битрикс.
На взятом интернет-магазине не устанавливались бета версии обновлений, и я буду на него ставить сразу релизные обновления.
После установки обновлений и рефреша (обновления) страницы я вижу следующую картину:
Самый короткий отчёт о работе отдела за всё время. Весь месяц отдел работал над АПИ докой по D7. Поэтому видимых изменений по доке - "кот наплакал". Делать АПИ по D7 будем ещё примерно с месяц. Надеемся под майские выпустить её.
Те из вас, кто следят за нашими группами в социальных сетях, а особенно те, кто подписан непосредственно на наших основных ньюс-мейкеров, наверняка заметили, насколько актуальна для нас становится тема чат-ботов в Битрикс24. Некоторые партнеры на своих порталах уже даже пообщались с нашей Мартой – самообучающейся системой, которая переписывается с пользователями в чате на естественном языке. Марта будет помогать пользователям Битрикс24 осваивать продукт, с каждым днем делая это все лучше и лучше.
Однако чат-бот, который умеет общаться на естественном языке - это достаточно специфичная и сложная штука, в то время как сам принцип чат-ботов как приложений позволяет решать массу задач и без всякого искусственного интеллекта в удобной для пользователей форме.
Хочется сделать небольшое отступление для тех, кто еще слабо понимает, что такое чат-боты, зачем они нужны и зачем вообще заниматься их разработкой. В большей степени этот тренд формируется сейчас за рубежом – существует огромное количество ботов для Slack или Telegram, решающих самые разные задачи – от поиска авиабилетов, до управления небольшими командами разработчиков. И чтобы получить все это богатство пользователям даже не нужно выходить из предпочитаемого мессенджера.
В этом весь смысл – можно разработать мобильное приложение для вызова такси, делать его для всех мобильных платформ, затем поддерживать совместимость и т.д. А можно написать чатбота для Telegram, которому пользователь просто напишет в чате “трансфер до Шереметьево”, и бот подберет варианты и покажет их, либо сразу сформирует заказ. Пользователю не надо ставить отдельное приложение, не надо осваивать интерфейс, а разработчикам не надо с этим же интерфейсом париться. Есть огромное количество сценариев, в которых использование чатботов удобнее для пользователей. Не буду переписывать уже известные материалы, полагаю, вы и сами сможете их найти, когда заинтересуетесь темой. Но начать можно, например, со статьи про нашествие ботов
Тем, кто сомневается, что это направление разработки играет какую-то заметную роль на рынке, могу порекомендовать переводной материал про грядущий Messenger Bot Store от Facebook, который, судя по оценкам, полностью перевернет текущее положение вещей
Чатботы в Битрикс24
И здесь мы плавно подходим к тому, какое отношение этот тренд имеет к Битрикс24. Ведь что такое Slack, Telegram, What’sUp, Viber и т.д.? Это мессендеры, которые живут «сами по себе».
А в Битрикс24 чаты (как индивидуальные, так и групповые) – это часть намного более сложной экосистемы, один из основных каналов коммуникации пользователей, полностью интегрированный с другими бизнес-инструментами. И в этом контексте использование чатботов открывает значительно более интересные перспективы для бизнес-пользователей, поскольку Битрикс24 (в браузере, десктоп-приложении и мобильном аппе) уже сейчас – основное рабочее место для большого количества компаний.
Очень просто написать бота, который, например, будет сообщать в чат нужным пользователям срочную информацию о показателях внутренней учетной системы, интегрированной с Битрикс24. Можно написать чатбота, который будет помогать курьерам удобно обрабатывать заказы на основании сделок CRM Битрикс24 на мобильном устройстве прямо в мессенджере – и не придется писать для них отдельное мобильное приложение.
Разработка чатбота в Битрикс24 – это очень перспективный вариант быстрой и удобной автоматизации специфических бизнес-процессов. Удобной, поскольку, как мы уже выяснили, получение информации и управление через мессенджер – это то, что сейчас предпочитает массовый пользователь. А быстрой – потому что разработка чатбота для Битрикс24 это довольно простая штука.
Давайте напишем такого бота прямо сейчас!
Самое главное
Прежде всего, чатбот в терминах Битрикс24 – это не отдельный тип приложений, и принципы разработки, в общем-то, укладываются в общие правила. Будем считать, что вы знакомы с созданием приложений для Битрикс24, чтобы сейчас не останавливаться на базовых вещах. Тем, кто еще такой разработкой не занимался, давно пора посмотреть наш видео-курс.
По отношению к материалам курса было сделано одно небольшое изменение – теперь есть возможность указать отдельный скрипт установки для приложений, которые используют только REST API и не встраиваются в интерфейс Б24. Это сделано для упрощения регистрации ботов в системе, хотя никто не запрещает пользоваться этим механизмом и для установки «обычных внешних приложений».
Вернемся к чатботам. Основное, что нам надо про них понимать – это то, что их логика обычно строится на реагировании на некие действия пользователя и системы. И у нас есть 4-е события, которые полностью покрывают необходимый спектр реакций:
Событие: ONAPPINSTALL Когда происходит: При установке приложения с чатботом Что получает обработчик:
[data] => Array(
[LANGUAGE_ID] - базовый язык портала
[VERSION] = 1 - версия приложения
)
[auth] => Array(
[access_token] => lh8ze36o8ulgrljbyscr36c7ay5sinva // ключ для отправки запросов к REST-сервису
[scope] => imbot // разрешенные уровни доступа
[domain] => b24.hazz // домен портала Битрикс24 на который было установлено приложение
[application_token] => c917d38f6bdb84e9d9e0bfe9d585be73 // токен приложения, поможет вам "отбивать" лишние запросы на обработчик события, это поле есть во всех событиях
[expires_in] => 3600 // время истечения токена, после которого нужно будет запросить новый
[member_id] => d41d8cd98f00b204e9800998ecf8427e // уникальный идентификатор портала, потребуется для продления авторизации
[refresh_token] => 5f1ih5tsnsb11sc5heg3kp4ywqnjhd09 // ключ для продления авторизации
)
Событие: ONIMBOTJOINCHAT Когда происходит: После приглашения бота «к разговору», то есть, либо при вызове бота пользователем в индивидуальном чате, либо при подключении бота к групповому чату Что получает обработчик:
[BOT] => Array // Массив кодов ботов, которым предназначено событие
(
[39] => Array // Параметры для авторизации под ботом, для выполнения действий
(
[domain] => b24.hazz
[member_id] => d41d8cd98f00b204e9800998ecf8427e
[application_token] => a63b44dc03a2158cb140c71d3f632a41
[bot_id] => 39
[bot_code] => newbot
)
)
[PARAMS] => Array
(
[DIALOG_ID] => 1 // идентифкатор диалога
[BOT_ID] => 39 // Идентификатор бота
[CHAT_TYPE] => P // Тип сообщения и чата, может быть P (чат один-на-один), C (с ограниченным кол-во участников), O (публичный чат)
[USER_ID] => 1 // идентификатор пользователя (для чата один-на-один открываший бота, для групповых чатов пригласивший бота)
[LANGUAGE] => RU // идентификатор языка портала по умолчанию
)
[USER] => Array // Массив данных пользователя, может быть пустым если ID = 0
(
[ID] => 1 // идентификатор пользователя
[NAME] => Евгений Шеленков // Имя и фамилия пользователя
[FIRST_NAME] => Евгений // Имя пользователя
[LAST_NAME] => Шеленков // Фамилия пользователя
[WORK_POSITION] => // Занимаемая должность
[GENDER] => M // Пол, может быть либо M (мужской) и F (женский)
)
Событие: ONIMBOTMESSAGEADD Когда происходит: После отправки сообщения от пользователя к боту (в групповом чате, при явном упоминании бота) Что получает обработчик:
[BOT] => Array // Массив кодов ботов, которым предназначено сообщение
(
[39] => Array // Параметры для авторизации под ботом, для выполнения действий
(
[domain] => b24.hazz
[member_id] => d41d8cd98f00b204e9800998ecf8427e
[application_token] => a63b44dc03a2158cb140c71d3f632a41
[bot_id] => 39
[bot_code] => newbot
)
)
[PARAMS] => Array // Массив данных сообщения
(
[DIALOG_ID] => 1 // идентифкатор диалога
[CHAT_TYPE] => P // Тип сообщения и чата, может быть P (чат один-на-один), C (с ограниченным кол-во участников), O (публичный чат)
[MESSAGE_ID] => 392 // Идентификатор сообщения
[MESSAGE] => test3 // Сообщение
[MESSAGE_ORIGINAL] => [USER=39]NewBot[/USER] test3 // оригинальное сообщение с BB-кодом бота (параметр доступен только в групповых чатах)
[FROM_USER_ID] => 1 // идентификатор пользователя отправившего сообщение
[TO_USER_ID] => 1 // идентификатор чат бота (параметр доступн только в чатах один-на-один)
[TO_CHAT_ID] => 6 // идентификатор чата (параметр доступен только в групповых чатах)
[LANGUAGE] => RU // идентификатор языка портала по умолчанию
)
[USER] => Array // Массив данных автора сообщения, может быть пустым если ID = 0
(
[ID] => 1 // идентификатор пользователя
[NAME] => Евгений Шеленков // Имя и фамилия пользователя
[FIRST_NAME] => Евгений // Имя пользователя
[LAST_NAME] => Шеленков // Фамилия пользователя
[WORK_POSITION] => // Занимаемая должность
[GENDER] => M // Пол, может быть либо M (мужской) и F (женский)
)
Событие: ONIMBOTDELETE Когда происходит: После удаления приложения. Событие вызывается параллельно с OnAppUninstall Что получает обработчик:
ONIMBOTDELETE После удаления приложения. Событие вызывается параллельно с OnAppUninstall
Иными словами, мы должны написать обработчики указанных событий, чтобы реализовать простую логику:
Зарегистрировать чатбота на портале пользователя при установке
Вывести приветствие-справку от имени бота в момент приглашения бота в чат
Научиться анализировать текст сообщения от пользователя и что-то отправлять в ответ, причем под анализом мы подразумеваем простой «разбор командной строки», а не лексический разбор естественного языка.
И для этого у нас есть набор простых методов, добавленных в REST API специально для чатботов, нам для старта потребуются только два:
Метод: imbot.register Что делает: Регистрирует бот на портале Какие параметры принимает:
Array(
'CODE' => 'newbot', // строковой идентификатор бота, уникальный в рамках вашего приложения (обяз.)
'TYPE' => 'H', // Тип бота, B - бот, ответы поступают сразу, H - человек, ответы поступаю с задержкой от 2х до 10 секунд
'EVENT_MESSAGE_ADD' => 'http://www.hazz/chatApi/event.php', // Ссылка на обработчик события отправки сообщения боту (обяз.)
'EVENT_WELCOME_MESSAGE' => 'http://www.hazz/chatApi/event.php', // Ссылка на обработчик события открытия диалога с ботом или приглашения его в групповой чат (обяз.)
'EVENT_BOT_DELETE' => 'http://www.hazz/chatApi/event.php', // Ссылка на обработчик события удаление бота со стороны клиента (обяз.)
'PROPERTIES' => Array( // Личные данные чат-бота (обяз.)
'NAME' => 'NewBot', // Имя бота (обязательное одно из полей NAME или LAST_NAME)
'LAST_NAME' => '', // Фамилия бота (обязательное одно из полей NAME или LAST_NAME)
'COLOR' => 'GREEN', // Цвет бота для мобильного приложения RED, GREEN, MINT, LIGHT_BLUE, DARK_BLUE, PURPLE, AQUA, PINK, LIME, BROWN, AZURE, KHAKI, SAND, MARENGO, GRAY, GRAPHITE
'EMAIL' => 'test@test.ru', // Емейл для связи
'PERSONAL_BIRTHDAY' => '2016-03-11', // День рождения в формате YYYY-mm-dd
'WORK_POSITION' => 'Мой первый бот', // Занимаемая должность, используется как описание бота
'PERSONAL_WWW' => 'http://test.ru', // Ссылка на сайт
'PERSONAL_GENDER' => 'F', // Пол бота, допустимые значения M - мужской, F - женский, пусто если не требуется указывать
'PERSONAL_PHOTO' => '/* base64 image */', // Аватар бота - base64
)
)
Метод: imbot.message.add Что делает: Добавляет в чат сообщение от имени чатбота Какие параметры принимает:
Array(
'BOT_ID' => 39, // идентификатор бота от которого идет запрос, можно не указывать если бот всего один
'DIALOG_ID' => 1, // идентификатор диалога, это либо USER_ID пользователя, либо chatXX - где XX идентификатор чата, передается в событии ONIMBOTMESSAGEADD и ONIMJOINCHAT
'MESSAGE' => 'answer text' // тест сообщения
'ATTACH' => '' // Вложение, не обязательное поле
'SYSTEM' => 'N' // отображать сообщения в виде системного сообщения, не обязательное поле, по умолчанию 'N'
'URL_PREVIEW' => 'Y' // преобразовывать ссылки в rich-ссылки, не обязательное поле, по умолчанию 'Y'
)
Очевидно, что в обработчике события ONAPPINSTALL мы вызовем метод imbot.register для того, чтобы добавить чатбота на текущий портал, затем в событии ONIMBOTJOINCHAT воспользуемся методом imbot.message.add для вывода справки о функционале бота, и в обработчике ONIMBOTMESSAGEADD будем отвечать пользователю при помощи того же imbot.message.add. Ничего сложного, согласитесь?
А на самом деле, вы поймете, что все еще проще, когда я добавлю, что вам не придется реализовывать в приложение полноценный OAuth 2.0, поскольку параметры, необходимые для авторизации приходят в обработчики в массиве $_REQUEST.
Готовый пример
В качестве примера я решил написать чатбота, который будет сообщать пользователю о его просроченных задачах. Наш бот будет знать и обрабатывать только одну команду «Что горит». По аналогии всегда можно расширить его функционал, чтобы получать прямо в чат нужные отчеты на основании любых данных в Битрикс24.
Небольшое замечание, коллеги: всем захочется взять готовый пример (я вот так и сделал - взял у Евгения Шеленкова), добавить парочку команд и поделиться этим прекрасным продуктом со всеми, опубликовав решение сразу в Приложениях24. Я вас очень прошу, давайте ответственно подойдем к разработке тиражных ботов и прежде, чем публиковать, научим их чему-то действительно интересному.
<?php
/**
* Полезный чат-бот c отчетами для bitrix24
*/
$appsConfig = array();
$configFileName = '/config_' . trim(str_replace('.', '_', $_REQUEST['auth']['domain'])) . '.php';
if (file_exists(__DIR__ . $configFileName)) {
include_once __DIR__ . $configFileName;
}
// receive event "new message for bot"
if ($_REQUEST['event'] == 'ONIMBOTMESSAGEADD') {
// check the event - register this application or not
if (!isset($appsConfig[$_REQUEST['auth']['application_token']])) {
return false;
}
// response time
$arReport = getAnswer($_REQUEST['data']['PARAMS']['MESSAGE'], $_REQUEST['data']['PARAMS']['FROM_USER_ID']);
$arReport['attach'][] = array("MESSAGE" => 'Как разберетесь с этими задачами, просто спросите еще раз [send=что горит]Что горит?[/send] и я дам новую сводку!');
// send answer message
$result = restCommand('imbot.message.add',
array(
"DIALOG_ID" => $_REQUEST['data']['PARAMS']['DIALOG_ID'],
"MESSAGE" => $arReport['title'] . "\n" . $arReport['report'] . "\n",
"ATTACH" => array_merge(
$arReport['attach']
),
),
$_REQUEST["auth"]);
} // receive event "open private dialog with bot" or "join bot to group chat"
else {
if ($_REQUEST['event'] == 'ONIMBOTJOINCHAT') {
// check the event - register this application or not
if (!isset($appsConfig[$_REQUEST['auth']['application_token']])) {
return false;
}
// send help message how to use chat-bot. For private chat and for group chat need send different instructions.
$result = restCommand('imbot.message.add', array(
'DIALOG_ID' => $_REQUEST['data']['PARAMS']['DIALOG_ID'],
'MESSAGE' => 'Привет! Я Докладун, докладываю все как есть.',
"ATTACH" => array(
array('MESSAGE' => '[send=что горит]Что горит?[/send]'),
),
), $_REQUEST["auth"]);
} // receive event "delete chat-bot"
else {
if ($_REQUEST['event'] == 'ONIMBOTDELETE') {
// check the event - register this application or not
if (!isset($appsConfig[$_REQUEST['auth']['application_token']])) {
return false;
}
// unset application variables
unset($appsConfig[$_REQUEST['auth']['application_token']]);
// save params
saveParams($appsConfig);
} // receive event "Application install"
else {
if ($_REQUEST['event'] == 'ONAPPINSTALL') {
// handler for events
$handlerBackUrl = ($_SERVER['SERVER_PORT'] == 443 ? 'https' : 'http') . '://' . $_SERVER['SERVER_NAME'] . (in_array($_SERVER['SERVER_PORT'],
array(80, 443)) ? '' : ':' . $_SERVER['SERVER_PORT']) . $_SERVER['SCRIPT_NAME'];
// If your application supports different localizations
// use $_REQUEST['data']['LANGUAGE_ID'] to load correct localization
// register new bot
$result = restCommand('imbot.register', array(
'CODE' => 'ReportBot',
// строковой идентификатор бота, уникальный в рамках вашего приложения (обяз.)
'TYPE' => 'B',
// Тип бота, B - бот, ответы поступают сразу, H - человек, ответы поступаю с задержкой от 2х до 10 секунд
'EVENT_MESSAGE_ADD' => $handlerBackUrl,
// Ссылка на обработчик события отправки сообщения боту (обяз.)
'EVENT_WELCOME_MESSAGE' => $handlerBackUrl,
// Ссылка на обработчик события открытия диалога с ботом или приглашения его в групповой чат (обяз.)
'EVENT_BOT_DELETE' => $handlerBackUrl,
// Ссылка на обработчик события удаление бота со стороны клиента (обяз.)
'PROPERTIES' => array( // Личные данные чат-бота (обяз.)
'NAME' => 'Докладун',
// Имя бота (обязательное одно из полей NAME или LAST_NAME)
'LAST_NAME' => '',
// Фамилия бота (обязательное одно из полей NAME или LAST_NAME)
'COLOR' => 'AQUA',
// Цвет бота для мобильного приложения RED, GREEN, MINT, LIGHT_BLUE, DARK_BLUE, PURPLE, AQUA, PINK, LIME, BROWN, AZURE, KHAKI, SAND, MARENGO, GRAY, GRAPHITE
'EMAIL' => 'no@mail.com',
// Емейл для связи
'PERSONAL_BIRTHDAY' => '2016-03-23',
// День рождения в формате YYYY-mm-dd
'WORK_POSITION' => 'Докладываю о делах',
// Занимаемая должность, используется как описание бота
'PERSONAL_WWW' => '',
// Ссылка на сайт
'PERSONAL_GENDER' => 'M',
// Пол бота, допустимые значения M - мужской, F - женский, пусто если не требуется указывать
'PERSONAL_PHOTO' => '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',
// Аватар бота - base64
),
), $_REQUEST["auth"]);
// save params
$appsConfig[$_REQUEST['auth']['application_token']] = array(
'BOT_ID' => $result['result'],
'LANGUAGE_ID' => $_REQUEST['data']['LANGUAGE_ID'],
);
saveParams($appsConfig);
// write debug log
// writeToLog($result, 'ReportBot register');
}
}
}
}
/**
* Save application configuration.
*
* @param $params
*
* @return bool
*/
function saveParams($params) {
$config = "<?php\n";
$config .= "\$appsConfig = " . var_export($params, true) . ";\n";
$config .= "?>";
$configFileName = '/config_' . trim(str_replace('.', '_', $_REQUEST['auth']['domain'])) . '.php';
file_put_contents(__DIR__ . $configFileName, $config);
return true;
}
/**
* Send rest query to Bitrix24.
*
* @param $method - Rest method, ex: methods
* @param array $params - Method params, ex: array()
* @param array $auth - Authorize data, ex: array('domain' => 'https://test.bitrix24.com', 'access_token' => '7inpwszbuu8vnwr5jmabqa467rqur7u6')
*
* @return mixed
*/
function restCommand($method, array $params = array(), array $auth = array()) {
$queryUrl = 'https://' . $auth['domain'] . '/rest/' . $method;
$queryData = http_build_query(array_merge($params, array('auth' => $auth['access_token'])));
// writeToLog(array('URL' => $queryUrl, 'PARAMS' => array_merge($params, array("auth" => $auth["access_token"]))), 'ReportBot send data');
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_POST => 1,
CURLOPT_HEADER => 0,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $queryUrl,
CURLOPT_POSTFIELDS => $queryData,
));
$result = curl_exec($curl);
curl_close($curl);
$result = json_decode($result, 1);
return $result;
}
/**
* Write data to log file.
*
* @param mixed $data
* @param string $title
*
* @return bool
*/
function writeToLog($data, $title = '') {
$log = "\n------------------------\n";
$log .= date("Y.m.d G:i:s") . "\n";
$log .= (strlen($title) > 0 ? $title : 'DEBUG') . "\n";
$log .= print_r($data, 1);
$log .= "\n------------------------\n";
file_put_contents(__DIR__ . '/imbot.log', $log, FILE_APPEND);
return true;
}
/**
* Формируем отчет по команде
*
* @param string $text строка, которую отправил юзер
* @param int $user идентификатор пользователя, который нам написал
*
* @return array
*/
function getAnswer($command = '', $user) {
switch (strtolower($command)) {
case 'что горит':
$arResult = b24BadTasks($user);
break;
default:
$arResult = array(
'title' => 'Туплю-с',
'report' => 'Не соображу, что вы хотите узнать. А может вообще не умею...',
);
}
return $arResult;
}
function b24BadTasks ($user) {
$tasks = restCommand('task.item.list',
array(
'ORDER' => array('DEADLINE' => 'desc'),
'FILTER' => array('RESPONSIBLE_ID' => $user, '<DEADLINE' => '2016-03-23'),
'PARAMS' => array(),
'SELECT' => array()
),
$_REQUEST["auth"]);
if (count($tasks['result']) > 0) {
$arTasks = array();
foreach ($tasks['result'] as $id => $arTask) {
$arTasks[] = array(
'LINK' => array(
'NAME' => $arTask['TITLE'],
'LINK' => 'https://'.$_REQUEST['auth']['domain'].'/company/personal/user/'.$arTask['RESPONSIBLE_ID'].'/tasks/task/view/'.$arTask['ID'].'/'
)
);
$arTasks[] = array(
'DELIMITER' => array(
'SIZE' => 400,
'COLOR' => '#c6c6c6'
)
);
}
$arReport = array(
'title' => 'Да, кое-какие задачи уже пролетели, например:',
'report' => '',
'attach' => $arTasks
);
}
else {
$arReport = array(
'title' => 'Шикарно работаете!',
'report' => 'Нечем даже огорчить - ни одной просроченной задачи',
);
}
return $arReport;
}
Вы уже сейчас можете взять этот код, выложить на своем сервере и запустить бота на своем портале, не публикуя его через Приложения24. Для этого в Битрикс24 есть возможность устанавливать локальные приложения.
Идем в раздел левого меню «Приложения» – «Добавить приложение» и выбираем вариант «Для личного пользования».
Указываем название бота, а называться он у нас будет «Докладун», включаем опцию «Приложение использует только API», и даем приложению права доступа на «Создание и управление чат-ботами» (без этих прав приложение не сможет зарегистрировать бота), а также на «Задачи» и «Задачи (расширенные права)» (без этих прав приложение не сможет сформировать отчет по задачам, чтобы сообщить о них через бота пользователю).
Поскольку наш скрипт написан таким образом, что является обработчиком всех событий, то в форме приложения мы укажем обе ссылки на один и тот же URL.
Собственно, уже все. Чудо должно произойти практически сразу – в общем чате появится сообщение о том, что к порталу присоединился новый пользователь: чатбот по имени Докладун.
Мы можем открыть с ним чат, нажать на ссылку «Что горит?» и получить свой список просроченных задач.
Теперь о некоторых нюансах в коде.
При регистрации чатбота в обработчике ONAPPINSTALL Битрикс24 передает нам новый параметр авторизации application_token. Все последующие вызовы обработчиков событий также будут содержать этот ключ, позволяя нам таким нехитрым способом проверять, а действительно ли получили получаем дальнейшие вызовы обработчиков событий вроде ONIMBOTMESSAGEADD от Битрикс24?
Мы сохраняем этот ключ, вызывая saveParams в строке 106, а в дальнейшем проверяем, в частности, в строках 14-16 и 36-38.
Еще один нюанс, на который хотелось бы обратить внимание – это возможность при регистрации бота указать разные URL для обработки разных событий. Именно эти URL прописаны в примере в строках 74-78. В нашем случае мы отдельные адреса не используем, но возможность такая есть.
Саму логику ответов чатбота мы вынесли в метод getAnswer, который получает всего два параметра – целиком весь текст, который напечатал в чат пользователь, и идентификатор этого самого пользователя.
Метод исключительно простой, реагирует он на одну единственную команду “что горит”, получает просроченные задачи текущего пользователя вызывая метод REST API task.item.list (поэтому, если захотите этого чатбота на своем портале потестировать - не забудьте дать права приложению на задачи!). Отчет формируется в виде списка ссылок с разделителем. Здесь можно использовать все богатство возможностей CHAT API, подробности которого описаны в статье
Обратите внимание на хитрое форматирование с тэгом [send], при помощи которого мы формируем команду для бота, а пользователю не приходится ничего набирать. Есть два варианта - мы можем сразу отослать команду по клику, и мы можем написать за пользователя команду и предложить ему дописать какие-то параметры.
[send=текст]название кнопки[/send] - мгновенно отправляет «текст» боту [put=подсказка]название кнопки[/put] - вставляет «подсказка» в поле ввода за пользователя, далее, пользователь просто дописывает, что необходимо и может отправлять сообщение боту.
Очень удобная штука, чтобы сделать общение с ботом еще проще. В нашем примере мы как раз и предлагаем пользователю не набирать нашу единственную команду «Что горит», а просто кликнуть по соответствующей ссылке.
Помимо этих тэгов, вы можете использовать для оформления сообщений известные всем BB-коды B, U, I, S и BR.
Пожалуй, для начала более, чем достаточно. Вы можете попробовать написать своих ботов уже сейчас. Подробная документация выйдет в апреле, а описание базовых вещей вы, не откладывая, можете прочитать в соответствующей группе на портале для разработчиков Маркетплейс.
Это открытое коммьюнити, там можно легко зарегистрироваться, перейдя по ссылке. Сама документация, равно как и ее последующие обновления, будет выкладываться в группе
Между прочим, скоро появится поддержка slash-команд, которые позволят вызывать ботов из групповых чатов без явного приглашения в чат и даже позволят обращаться к ботам из комментариев живой ленты! Но об этом – в следующих материалах!
В ближайшем обновлении модуля sale версии 16.0.13 будет доступен новый функционал обмена с 1С. Обновленный модуль 1С можно скачать на странице http://1c.1c-bitrix.ru/ecommerce/download.php версия 6 и выше.
В обмен добавлена работа с документами частичных оплат и частичных отгрузок. Обмен данными по заказу будет происходит не в рамках одного документа заказа как раньше, а в рамках 3х документов.
Документ Заказа
Документ Оплаты
Документ Отгрузки
Каждый из этих документов в БУС может создаваться, обновляться, отменяться по отдельности своим отдельным документом от 1С
Изменения в экспорте. БУС -> 1С Основное изменение - для каждого заказа создаётся структура документов вида
Документ.Заказ1
Документ.Оплата1 (Основание Заказ1)
Документ. ОплатаN (Основание Заказ1)
Документ.Отгрузка1 (Основание Заказ1)
Документ. ОтгрузкаN (Основание Заказ1)
Документ отгрузок содержит табличную часть позиций заказа соответствующей частичной отгрузки. Таким образом данные по заказу выгружаются в одном документе заказа, данные по оплатам и отгрузкам могут выгружаться в неограниченном количестве документов связанных с заказом через поле <Основание>...</Основание> При этом заказ выгружается всегда, документы оплаты и отгрузки выгружаются если они есть в любых статусах.
Изменения в импорте. 1С->БУС
Перед запуском необходимо выполнить предварительные настройки
Уже давно пользователям Битрикс24 помогает контекстная помощь. Находясь на любой странице портала нажимаем на знак вопроса и получаем ответы на самые актуальные вопросы:
Возможности работы с сессиями в продукте значительно расширились. Появилась возможность в качестве хранилища сессии использовать memcached, не блокирующая и виртуальная сессия. Остановимся подробнее на этих возможностях.
1. Хранение сессий в memcached
Для включения хранения сессий в memcached необходимо в /bitrix/php_interface/dbconn.php или /local/php_interface/dbconn.php установить следующие константы
После этого, включить в модуле проактивной защиты, хранение сессий в базе данных. В результате получаем хранение сессий в memcached средствами ядра. Данный способ хранения сессий дает следующие преимущества:
- нет необходимости следить за количеством старых сессий на нагруженном проекте - возможность разделять сессии между серверами в кластере - возможность использовать не ожидающую получения блокировки сессию - возможность использовать виртуальные сессии
В целом хранение сессий в БД имеет такие же преимущества, но в отличие от хранения сессий в memcached, значительно более медленное. Поэтому рекомендуем использовать хранение сессий в memcached, взамен хранения сессий в БД.
2. Не блокирующие сессии.
Одной из проблем больших проектов с множественными аякс запросами, является частые блокировки хитов одного пользователя на ожидание получения блокировки сессии. Особенно это актуально для КП, где во многих местах прикрепленные к сущностям файлы отдаются пользователю, после проверки прав на php. Поэтому на страницах возможно построение лесенки, из за ожидания получения блокировки сессии. Включить не блокирующую сессию можно установкой константу, до подключения ядра продукта.
define('BX_SECURITY_SESSION_READONLY', true);
После этого сессия читается из memcached или БД не ожидая получения блокировки. Важно помнить, что при использование данной константы по завершению хита, сессия не будет записана. Что может привести к потере данных сохраненных в рамках хита в сессии. Внутри продукта данная функциональность используется например при отдаче отдаче файлов.
3. Виртуальные сессии.
Не блокирующих сессий, для большинства кейсой достаточно. Но в некоторых ситуациях, когда сессия нам не нужна совсем, использование не блокирующей сессии все таки избыточно. Так как сессия будет создаваться в случае ее отсутствия. В результате при большом количестве не связанных между собой хитов, будет созданно большое количество мусорных сессий. Примером таких хитов, являются хиты реста. Для решения этой проблемы была добавлена "Виртуальная сессия". Суть которой заключается в том, что сессия создается в памяти, не ждет блокировок и не сохраняется. Для ее включения необходимо установить константу, до подключения ядра продукта.
define('BX_SECURITY_SESSION_VIRTUAL', true);
Особо стоит обратить внимание на то, что данный тип сессии никак не сохраняется. В продукте используется при обработке рест запросов.
В качестве небольшого заключения. Если у вас КП, проект с большим количеством ajax запросов или много файлов отдается с проверкой прав (например в блогах, соцсети, форуме) то лучше использовать хранение сессий в memcached средствами ядра.
Как вы знаете, БП поддерживают вычисление значений выражений в параметрах действий. Для практически любого параметра действия можно в качестве значения указать не только какое-то фиксированное значение (например, "Привет", не только переменную, параметр или поле документа (например, {=Variable:myVar}), но и вычисляемое выражение
Этот функционал можно использовать, например, чтобы задать период ожидания (жизни) действия ознакомления с документом не в секундах, а какой-то датой со временем. Это может быть полезно, если ждать выполнения действия ознакомления надо не определенное время, а до какого-то времени. Например, нет смысла ждать ознакомления с отгулом после даты отгула.
С использованием вычисляемых выражений эту задачу можно решить так: в поле ввода "Период ознакомления" нужно написать строку вида
={=Template:Parameter1 > int}-{=System:Now > int}
где Template:Parameter1 надо поменять на ту сущность, где хранится время. Например, это может быть Variable:MyVariable, если дата/время хранится в переменной, или Document:CREATE_DATE, если дата/время хранится в поле документа. Тип периода надо оставить в секундах. Обратите внимание, чтобы нигде у вас не было суффиксов _printable. Если с таймзонами все в порядке, то вы сразу получите ожидаемый результат. В противном случае надо будет прибавить или отнять столько секунд, чтобы компенсировать сдвиг.
Мы готовимся к выпуску нового модуля Интернет-магазина. Физически это - тот же самый модуль sale, но существенно переработанный. В новом магазине у одного заказа может быть множество отгрузок и оплат/счетов, систематизирована оплата с внутреннего счета, переработаны платежные системы и службы доставки с целью их универсализации и поддержки новых возможностей, переработан жизненный цикл заказа, доработаны публичные компоненты и добавлено множество других улучшений и функциональных возможностей.
При разработке мы старались максимально обеспечить совместимость нового магазина со старыми версиями, но обеспечить 100% совместимость при такой масштабной переработке невозможно. Ниже в статье я опишу места, на которые надо обратить особое внимание при переходе на новый магазин. Если у вас есть вопросы, предложения, пожелания или требуется консультация - обращайтесь к нам через службу техподдержки.
Существенно изменилась структура таблиц в базе данных. Мы всегда говорили, что прямой доступ к таблицам - это не правильный вариант работы с обновляемым продуктом. Но если вы все же по тем или иным причинам напрямую запрашиваете базу данных, то велика вероятность, что вам придется внести изменения в свои алгоритмы. Правильный доступ к данным должен производиться через АПИ модуля.
Заказ, оплаты, доставки – связь «один-ко-многим». Раньше в магазине была одна сущность - заказ, который представлял собой одну запись в таблице заказов. В этой таблице было поле, в котором хранился код платежной системы, поле со статусом оплаты и т.д. В новом магазине у каждого заказа может быть неограниченное число (частичных) оплат/счетов, а так же неограниченное число отгрузок. У каждой оплаты свой статус оплаченности, своя дата оплаты и т.п. Другими словами появляется связь «один-ко-многим» между заказом и оплатами/отгрузками. Соответственно если выбрать из базы пару значений "заказ - оплата", то либо оплата там будет какая-то одна из имеющихся (не все), либо один и тот же заказ будет в нескольких парах (по числу оплат). Мы постарались обеспечить максимально возможную совместимость. Если у вас не используется разделение на несколько оплат для одного заказа, то через старый АПИ можно выбрать сразу и заказ и его одну оплату. Но как только у вас появится разделение - результат выборки может оказаться не такой, на который вы рассчитываете. Все, что сказано про оплаты, верно и для отгрузок. Рекомендовать тут можно только либо постепенно переходить на новый АПИ в ваших решениях (рекомендуется), либо всегда для одного заказа иметь только одну оплату и только одну отгрузку.
Оплата с внутреннего счета. Раньше при оплате с внутреннего счета просто в таблице заказа проставлялась соответствующая сумма. В новом магазине внутренний счет - такая же платежная система, как и все остальные. Соответственно оплата с внутреннего счета - такая же запись (частичной) оплаты, как и для любой другой платежной системы. Таким образом облегчается отслеживание оплат, а кроме того на внутренний счет можно наложить условия и ограничения (как на любую другую платежную систему).
Полностью переработан жизненный цикл заказа. Так как изменилась структура и работа заказа, то соответственно изменился и жизненный цикл заказа. Мы восстановили основные события того жизненного цикла, который был раньше. Они включаются и выключаются в настройках модуля. Но места вызова старых событий в новом магазине не соответствуют старым местам вызова (потому что старых мест уже нет). В большинстве случаев это не должно повлиять на успешное выполнение вашего обработчика события, но лучше после перехода на новый магазин перепроверить, что все работает правильно. Еще лучше, конечно, перейти на новые события.
Новый АПИ автоматически всегда поддерживает арифметическую целостность заказа. Раньше программно можно было записать в любые поля заказа любые значения, и это успешно сохранялось, даже если логически данные не соответствовали друг другу. Например, при использовании старого АПИ можно было создать заказ стоимостью 1 руб., в котором было товаров на 500 руб. В новом магазине стоимость такого заказа будет 500 руб. (плюс возможно стоимость доставки).
Меняются реальные ID платежных систем и служб доставок. В связи с изменением структуры и работы платежных систем и служб доставок, меняются их реальные ID. У служб доставок теперь нет архитектурного разделения на настраиваемые и автоматизированные, соответственно нет и строковых идентификаторов, они теперь числовые. Все внутренние данные и сущности сами переходят на новые ID при конвертации. Если вы где-то используете связывание внешних по отношению к модулю данных с платежными системами или службами доставок, то вам необходимо убедиться в корректном сохранении связей. А вообще правильнее такие связи делать через внешние ключи или мнемонические коды.
Ограничения платежных систем и служб доставок. Раньше ограничения платежных систем и служб доставок (например, по сайтам, типам плательщика и т.п.) – были поля в таблицах соответственно платежных систем и служб доставок. Как следствие схема была не множественной и не расширяемой. Сейчас ограничения задаются с помощью новой сущности - ограничений. Они стали набираемыми для каждой службы доставки и платежной системы. Соответственно они могут быть множественными, можно расширять набор ограничений и т.д. Но следует учитывать, что это - больше не поля в таблице.
Пользовательские платежные системы. Обратите внимание, что пользовательские обработчики платежных систем должны лежать в папке /bitrix/php_interface/include/sale_payment/. Они не могут лежать внутри /bitrix/modules/sale/. Внутри ядра продукта вы не должны ничего менять самостоятельно. Это прямо указано в документации. Так же обратите внимание на то, что в общем случае нельзя напрямую (через include) подключать файлы из ядра продукта в свои скрипты. Если вы копировали какие-то обработчики в пользовательскую папку для изменения, то вы должны скопировать все файлы обработчика, а не подключать часть из них из ядра.
Если у вас есть вопросы, предложения, пожелания или требуется консультация - обращайтесь к нам через службу техподдержки.
Очень простое и полезное API есть в продукте, которое достойно отдельного внимания! Наверняка еще не все знают
Для оформления и реализации front-end логики компонента, в его шаблоне доступны не обязательные файлы - style.css, который определяет стили, необходимые данному шаблону - script.js, который определяет и подключает яваскрипты, необходимые данному шаблону.
Не всегда их хватает. Для подключения внешних css/js можно было пойти разными путями
- В шаблоне "подключить жестко" инлайном, что совсем не спортивно
<li nk href="/local/styles.css" type="text/css" rel="stylesheet" />
- Захардкодить в компоненте (так как есть ловушка кеширования в шаблоне), что еще менее спортивно
У меня две новости. Обе хорошие. На этой неделе мы внедрили небольшие нововведения в процесс публикации приложений на BitrixMobile - статусы публикации и комментарии. А также стала доступна документация по разработке офлайн-приложений на нашей платформе.
Коллеги, знакома ли вам боль от вида фаталов в логах, происхождение которых остается загадкой? Больнее всего от каких-то часто используемых/общих методов:
PHP Fatal error: Call to a member function smthd() on null in /var/www/some/factory/generic.php on line 13
PHP Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 30148784 bytes) in /var/www/bitrix/modules/main/lib/text/string.php on line 24
Отлично PHP, я вижу OOM, но вызовов \Bitrix\Main\Text\String::htmlEncode несметное количество и начинать разборы причин попросту неоткуда, ведь кроме строки где мы упали и запроса пользователя ничего и нет. Язык для домашних страничек во всей красе, я считаю. К сожалению PHP 5.x (в PHP 7.x есть engine exceptions) не позволяет установить кастомный обработчик для ошибок типа E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR и E_COMPILE_WARNING, обоснованно считая это не безопасным. Поэтому ловить фаталы по аналогии с другими ошибками попросту не выйдет:( Из всех "не улавливаемых" ошибок наиболее любопытен E_ERROR, а типичное решение этой проблемы - зарегистрировать shutdown-функцию (register_shutdown_function) и там кетчить. Все в целом не так плохо, если вам не интересен stack trace, ибо его на момент вызова shutdown-функции уже нет.
Так родился небольшой PHP-extension PHP Fatal Error Handler, который позволяет прокинуть в user space ошибки типа E_ERROR, что дает возможность обработать их нужным образом (i.e. сохранить) и достойно "умереть". Стоит предупредить, что тут важно понимать что вы делаете и имплементить крайне аккуратно, ибо PHP обоснованно считает прокидывание ошибок этого типа не безопасным. Собирается как и любое другое расширения (детально описано в README) Пример использования:
Args:
array(4) {
[0]=>
int(1)
[1]=>
string(34) "Call to undefined function fatal()"
[2]=>
string(26) "/home/buglloc/tmp/test.php"
[3]=>
int(10)
}
Trace:
#0 {closure}(1, Call to undefined function fatal(), /home/buglloc/tmp/test.php, 10) called at [/home/buglloc/tmp/test.php:10]
#1 test_error() called at [/home/buglloc/tmp/test.php:13]
Больше примеров можно посмотреть в тестах или демо с реализацией простого хендлера ошибок/исключений:
<?php
require_once __DIR__ . '/handler.php';
$handler = new ErrorHandler;
$handler->register();
function foo() {
fatal();
}
function bar() {
foo();
}
// warning
strpos();
// fatal
bar();
Вывод:
E_WARNING: strpos() expects at least 2 parameters, 0 given in /home/buglloc/work/projects/php-fatal-handler/demo/test.php:16
#1 /home/buglloc/work/projects/php-fatal-handler/demo/test.php(16): strpos()
#2 {main}
E_ERROR: Call to undefined function fatal() in /home/buglloc/work/projects/php-fatal-handler/demo/test.php:9
#1 /home/buglloc/work/projects/php-fatal-handler/demo/test.php(13): foo()
#2 /home/buglloc/work/projects/php-fatal-handler/demo/test.php(19): bar()
#3 {main}
Ooops
Это лишь пример, для того что бы показать суть использования расширения, не стоит бездумно подключать его на бою.
Расширение должно работать со всей линейкой поддерживаемых версий PHP от 5.3 до 5.6, в том числе и с ZTS. За счет минимального оверхеда можно использовать в продакшене не боясь за производительность. Если будут какие-то вопросы, предложения, замечания можете адресовать их в багтрекер
1С-Битрикс Управления Сайтом предоставляет множество инструментов для оптимальной работы на мобильных устройствах, а также помогает разработчику быстро и просто оптимизировать работу с мобильными устройствами. Мы не раз писали и показывали как все это настраивать.
Отчитываемся немного с опозданием от обычных сроков, простите великодушно. Накопленный опыт по оценке способов сдачи позволяет более качественно выцеплять "гениев" сдающих по шпорам. Поэтому требования высказанные здесь будут несколько ужесточены. Надеемся, что нам опять удастся аккуратно пройти по натянутой нити и не задеть честных обучающихся. Подробнее о сделанном за январь под катом.
Коллеги, в Академии «1С-Битрикс» всем доступны видеокурсы. А зимние каникулы - отличное время посмотреть уроки Они наглядно продемонстрируют процесс разработки сайта и помогут основательно разобраться во многих вопросах работы платформы. Удивительно, но даже материалы первых курсов пришлись по душе опытным разработчикам.
В конце этого года появились новые курсы:
По разработке своего модуля на D7
Этот курс на практических примерах раскрывает вопрос создания своего модуля для Bitrix Framework, используя возможности нового ядра D7 - от идеи до конечной реализации. Вы узнаете о подходах к разработке своего модуля, файловой структуре модуля, организации хранения данных модуля, событиях, куче «плюшек» от использования ОRM и огромное количество другой полезной информации!
Разработка приложений для Маркетплейса «Битрикс24» – это новая ниша, которую могут занять наши партнеры - разработчики. В уроках курса последовательно и подробно рассматривается разработка приложения – от самого простого к сложному. Вы сможете легко разобраться и освоить создание приложений.
Курсы позволят очень просто разобраться с архитектурой продукта и начать профессиональную разработку.
Для опытных: курс №3 - Расширенные технологии и производительность, обширный курс по продвинутым возможностям платформы, перейти >>
И если так сложилось (мало ли как бывает ), вы создаете сайты на «1С-Битрикс» и еще ни разу не переводили сайт на композитный режим, то этот урок специально для вас!
С наступающим вас Новым годом, новых знаний и успешного их применения в 2016 году !
Хочу рассказать вам как сделать ваши уведомления и сообщения богаче используя новый инструмент "Вложения"
Я несколько раз анонсировал эту возможность и скорее всего вы уже начали думать о том, как использовать её у себя в модулях Сейчас я вам расскажу как это сделать, на самом деле это достаточно просто (приготовьтесь, пост длинный с картинками)
В этом месяце поставлен своеобразный рекорд: 38 аннулированных сертификатов. Как и в прошлый раз, похоже это одна компания начала массово сдавать на сертификаты, но по шпорам. Кстати, созрело понимание как дополнительно можно создать сложности для сдающих по шпорам или за деньги. В январе, скорее всего, аргументируем и введём новые меры. Теперь о том что сделано:
Пару дней назад мы выпустили гору обновлений для коробки, среди них обновления Веб-мессенджера 16.0.0, оно уже доступно для загрузки и ознакомления.
Про обновление для пользователей мы подробно рассказали в презентации и в блоге Битрикс24, а теперь я расскажу какие новинки уже есть и какие ждут разработчиков в декабре-январе
Браузер Google Chrome с версии 47 отключает WebRTC на всех сайтах, кто не использует протокол HTTPS. Это означает что для всех коробочных версий Битрикс24, у кого не стоит HTTPS сертификат, перестанет работать телефония и внутренние звонки.
Для решения проблемы, необходимо будет приобрести и настроить HTTPS сертификат для сайта, либо использовать Mozilla Firefox (но тоже временное решение, т.к. Firefox скорее всего тоже включит такое ограничение в следующем году)
Для пользователей это будет выглядеть, как "Невозможно получить доступ к веб-камере или микрофону". Для клиентов Битрикс24 облачной версии - это предупреждение не актуально, так как порталы изначально работают по протоколу HTTPS.
День добрый, рад официально сообщить - запустили новую систему сертификации разработчиков от «1С-Битрикс».
Мы уже обсуждали с вами в блоге экзамены, как они будут проходить, что мы будем проверять и как подготовиться. Теперь расскажу про уровни разработчиков, способы их достижения, цены на экзамены.