Пример коннектора Открытых линий для онлайн-чата на сайте
Внимание! Пример заработает только на локальном приложении, в случае использования вебхуков он не сработает.
Пример позволит создать на вашем сайте онлайн чат. Диалог привязывается к сессии пользователя на вашем сайте и домену.
- После установки всех файлов, запускаем через браузер файл install_connector.php для первоначальной настройки ОЛ. При успешной первоначальной настройке у вас отобразится надпись
successfully
. - Открыть раздел с открытыми линиями и там находим блок с названием "ExampleSiteChat".
- Открыв раздел с "ExampleSiteChat" нажимаем кнопку "подключить".
- Если вы всё верно настроили вам выдаст также надпись
successfully
. - Установка закончена, вы можете открыть файл index.php и начать первый диалог в чате.
В примере предусмотрена проверка: при вызове файла install_connector.php должна создаваться папка \chats
в той же директории, где расположен этот файл. В этой папке хранится информация по чатам.
Если появится сообщение: error creat dir /chats
, то первоначальная настройка коннектора не выполнилась, т.к. неверно настроены права и скрипт не может создать папку /chats
.
Создаём файл function.php:
<? include_once('crest.php'); function getConnectorID() { return 'example_connector_1'; } function getChat($chatID) { $result = []; if (file_exists(__DIR__ . '/chats/' . $chatID . '.txt')) { $result = json_decode(file_get_contents(__DIR__ . '/chats/' . $chatID . '.txt'), 1); } return $result; } function saveMessage($chatID, $arMessage) { $arMessages = getChat($chatID); $count = count($arMessages); $arMessages['message' . $count] = $arMessage; if (file_put_contents(__DIR__ . '/chats/' . $chatID . '.txt', json_encode($arMessages))) { $return = $count; } else { $return = false; } return $return; } function getLine() { return file_get_contents(__DIR__ . '/line_id.txt'); } function setLine($line_id) { return file_put_contents(__DIR__ . '/line_id.txt', intVal($line_id)); } function convertBB($var) { $search = array( '/\[b\](.*?)\[\/b\]/is', '/\[br\]/is', '/\[i\](.*?)\[\/i\]/is', '/\[u\](.*?)\[\/u\]/is', '/\[img\](.*?)\[\/img\]/is', '/\[url\](.*?)\[\/url\]/is', '/\[url\=(.*?)\](.*?)\[\/url\]/is' ); $replace = array( '<strong>$1</strong>', '<br>', '<em>$1</em>', '<u>$1</u>', '<img src="$1" />', '<a href="$1">$1</a>', '<a href="$1">$2</a>' ); $var = preg_replace($search, $replace, $var); return $var; }
Создаём файл handler.php:
Переменные $widgetUri и $widgetName обязательны, если необходимо чтобы данный коннектор отображался в списке коннекторов в виджете на сайте и соответственно выводился там. Иначе их можно не заполнять.
- widgetUri - Путь с иконки в виджете. (Например, при нажатии на иконку фейсбука открывается чат в фейсбуке.)
- widgetName - название коннектора в виджете.
<? require_once('function.php'); $widgetUri = '';//detail page chat "https://example.com/index.php" $widgetName = 'ExampleSiteChatWidget';//name connector in widget $connector_id = getConnectorID(); if (!empty($_REQUEST['PLACEMENT_OPTIONS']) && $_REQUEST['PLACEMENT'] == 'SETTING_CONNECTOR') { //activate connector $options = json_decode($_REQUEST['PLACEMENT_OPTIONS'], true); $result = CRest::call( 'imconnector.activate', [ 'CONNECTOR' => $connector_id, 'LINE' => intVal($options['LINE']), 'ACTIVE' => intVal($options['ACTIVE_STATUS']), ] ); if (!empty($result['result'])) { //add data widget if(!empty($widgetUri) && !empty($widgetName)) { $resultWidgetData = CRest::call( 'imconnector.connector.data.set', [ 'CONNECTOR' => $connector_id, 'LINE' => intVal($options['LINE']), 'DATA' => [ 'id' => $connector_id.'line'.intVal($options['LINE']),// 'url_im' => $widgetUri, 'name' => $widgetName ], ] ); if(!empty($resultWidgetData['result'])) { setLine($options['LINE']); echo 'successfully'; } } else { setLine($options['LINE']); echo 'successfully'; } } } if( $_REQUEST['event'] == 'ONIMCONNECTORMESSAGEADD' && !empty($_REQUEST['data']['CONNECTOR']) && $_REQUEST['data']['CONNECTOR'] == $connector_id && !empty($_REQUEST['data']['MESSAGES']) ) { foreach ($_REQUEST['data']['MESSAGES'] as $arMessage) { $idMess = saveMessage($arMessage['chat']['id'], $arMessage); $resultDelivery = CRest::call( 'imconnector.send.status.delivery', [ 'CONNECTOR' => $connector_id, 'LINE' => getLine(), 'MESSAGES' => [ [ 'im' => $arMessage['im'], 'message' => [ 'id' => [$idMess] ], 'chat' => [ 'id' => $arMessage['chat']['id'] ], ], ] ] ); } }
Создаём файл install_connector.php
необходимо указать в $handlerUrl путь до файла handler.php, созданного выше:<? require_once('function.php'); $handlerUrl = 'https://yourdomain.yyy/handler.php'; //creat dir for save chats (recommend using database) @mkdir(__DIR__ . '/chats/', 0775, true); if(!file_exists(__DIR__ . '/chats/')) { echo 'error creat dir "chats"'; } else { $connector_id = getConnectorID(); $result = CRest::call( 'imconnector.register', [ 'ID' => $connector_id, 'NAME' => 'ExampleSiteChat', 'ICON' => [ 'DATA_IMAGE' => 'data:image/svg+xml;charset=US-ASCII,%3Csvg%20version%3D%221.1%22%20id%3D%22Layer_1%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20x%3D%220px%22%20y%3D%220px%22%0A%09%20viewBox%3D%220%200%2070%2071%22%20style%3D%22enable-background%3Anew%200%200%2070%2071%3B%22%20xml%3Aspace%3D%22preserve%22%3E%0A%3Cpath%20fill%3D%22%230C99BA%22%20class%3D%22st0%22%20d%3D%22M34.7%2C64c-11.6%2C0-22-7.1-26.3-17.8C4%2C35.4%2C6.4%2C23%2C14.5%2C14.7c8.1-8.2%2C20.4-10.7%2C31-6.2%0A%09c12.5%2C5.4%2C19.6%2C18.8%2C17%2C32.2C60%2C54%2C48.3%2C63.8%2C34.7%2C64L34.7%2C64z%20M27.8%2C29c0.8-0.9%2C0.8-2.3%2C0-3.2l-1-1.2h19.3c1-0.1%2C1.7-0.9%2C1.7-1.8%0A%09v-0.9c0-1-0.7-1.8-1.7-1.8H26.8l1.1-1.2c0.8-0.9%2C0.8-2.3%2C0-3.2c-0.4-0.4-0.9-0.7-1.5-0.7s-1.1%2C0.2-1.5%2C0.7l-4.6%2C5.1%0A%09c-0.8%2C0.9-0.8%2C2.3%2C0%2C3.2l4.6%2C5.1c0.4%2C0.4%2C0.9%2C0.7%2C1.5%2C0.7C26.9%2C29.6%2C27.4%2C29.4%2C27.8%2C29L27.8%2C29z%20M44%2C41c-0.5-0.6-1.3-0.8-2-0.6%0A%09c-0.7%2C0.2-1.3%2C0.9-1.5%2C1.6c-0.2%2C0.8%2C0%2C1.6%2C0.5%2C2.2l1%2C1.2H22.8c-1%2C0.1-1.7%2C0.9-1.7%2C1.8v0.9c0%2C1%2C0.7%2C1.8%2C1.7%2C1.8h19.3l-1%2C1.2%0A%09c-0.5%2C0.6-0.7%2C1.4-0.5%2C2.2c0.2%2C0.8%2C0.7%2C1.4%2C1.5%2C1.6c0.7%2C0.2%2C1.5%2C0%2C2-0.6l4.6-5.1c0.8-0.9%2C0.8-2.3%2C0-3.2L44%2C41z%20M23.5%2C32.8%0A%09c-1%2C0.1-1.7%2C0.9-1.7%2C1.8v0.9c0%2C1%2C0.7%2C1.8%2C1.7%2C1.8h23.4c1-0.1%2C1.7-0.9%2C1.7-1.8v-0.9c0-1-0.7-1.8-1.7-1.9L23.5%2C32.8L23.5%2C32.8z%22/%3E%0A%3C/svg%3E%0A', 'COLOR' => '#a6ffa3', 'SIZE' => '100%', 'POSITION' => 'center', ], 'ICON_DISABLED' => [ 'DATA_IMAGE' => 'data:image/svg+xml;charset=US-ASCII,%3Csvg%20version%3D%221.1%22%20id%3D%22Layer_1%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20x%3D%220px%22%20y%3D%220px%22%0A%09%20viewBox%3D%220%200%2070%2071%22%20style%3D%22enable-background%3Anew%200%200%2070%2071%3B%22%20xml%3Aspace%3D%22preserve%22%3E%0A%3Cpath%20fill%3D%22%230C99BA%22%20class%3D%22st0%22%20d%3D%22M34.7%2C64c-11.6%2C0-22-7.1-26.3-17.8C4%2C35.4%2C6.4%2C23%2C14.5%2C14.7c8.1-8.2%2C20.4-10.7%2C31-6.2%0A%09c12.5%2C5.4%2C19.6%2C18.8%2C17%2C32.2C60%2C54%2C48.3%2C63.8%2C34.7%2C64L34.7%2C64z%20M27.8%2C29c0.8-0.9%2C0.8-2.3%2C0-3.2l-1-1.2h19.3c1-0.1%2C1.7-0.9%2C1.7-1.8%0A%09v-0.9c0-1-0.7-1.8-1.7-1.8H26.8l1.1-1.2c0.8-0.9%2C0.8-2.3%2C0-3.2c-0.4-0.4-0.9-0.7-1.5-0.7s-1.1%2C0.2-1.5%2C0.7l-4.6%2C5.1%0A%09c-0.8%2C0.9-0.8%2C2.3%2C0%2C3.2l4.6%2C5.1c0.4%2C0.4%2C0.9%2C0.7%2C1.5%2C0.7C26.9%2C29.6%2C27.4%2C29.4%2C27.8%2C29L27.8%2C29z%20M44%2C41c-0.5-0.6-1.3-0.8-2-0.6%0A%09c-0.7%2C0.2-1.3%2C0.9-1.5%2C1.6c-0.2%2C0.8%2C0%2C1.6%2C0.5%2C2.2l1%2C1.2H22.8c-1%2C0.1-1.7%2C0.9-1.7%2C1.8v0.9c0%2C1%2C0.7%2C1.8%2C1.7%2C1.8h19.3l-1%2C1.2%0A%09c-0.5%2C0.6-0.7%2C1.4-0.5%2C2.2c0.2%2C0.8%2C0.7%2C1.4%2C1.5%2C1.6c0.7%2C0.2%2C1.5%2C0%2C2-0.6l4.6-5.1c0.8-0.9%2C0.8-2.3%2C0-3.2L44%2C41z%20M23.5%2C32.8%0A%09c-1%2C0.1-1.7%2C0.9-1.7%2C1.8v0.9c0%2C1%2C0.7%2C1.8%2C1.7%2C1.8h23.4c1-0.1%2C1.7-0.9%2C1.7-1.8v-0.9c0-1-0.7-1.8-1.7-1.9L23.5%2C32.8L23.5%2C32.8z%22/%3E%0A%3C/svg%3E%0A', 'SIZE' => '100%', 'POSITION' => 'center', 'COLOR' => '#ffb3a3', ], 'PLACEMENT_HANDLER' => $handlerUrl, ] ); if (!empty($result['result'])) { $resultEvent = CRest::call( 'event.bind', [ 'event' => 'OnImConnectorMessageAdd', 'handler' => $handlerUrl, ] ); if (!empty($resultEvent['result'])) { echo 'successfully'; } } }
Создаём файл ajax.php:
<? require_once('function.php'); session_start(); $chatID = 'chat' . md5($_SERVER['HTTP_ORIGIN']) . md5(session_id()); $type = $_POST['type']; $connector_id = getConnectorID(); $line_id = getLine(); /* simple example save chat, must lost any data recommend using database */ if ($type == 'chat_history'): $arChat = getChat($chatID); if (!empty($arChat)): foreach ($arChat as $item):?> <div class="col-12 alert alert-warning text-<?=(!empty($item['im'])) ? 'left' : 'right'?>" style=" background-color: <?=(!empty($item['im'])) ? '#fbfbfb' : '#ccf2ff'?>"> <?=convertBB($item['message']['text'])?> </div> <? endforeach; endif; elseif ($type == 'send_message'): $arMessage = [ 'user' => [ 'id' => $chatID, 'name' => htmlspecialchars($_POST['name']), ], 'message' => [ 'id' => false, 'date' => time(), 'text' => htmlspecialchars($_POST['message']), ], 'chat' => [ 'id' => $chatID, 'url' => htmlspecialchars($_SERVER['HTTP_REFERER']), ], ]; $id = saveMessage($chatID, $arMessage); $result['error'] = 'error_save'; if ($id !== false) { $arMessage['message']['id'] = $id; $result = CRest::call( 'imconnector.send.messages', [ 'CONNECTOR' => $connector_id, 'LINE' => $line_id, 'MESSAGES' => [$arMessage], ] ); } echo json_encode( [ 'chat' => $chatID, 'post' => $_POST, 'result' => $result ] ); endif;
Создаём файл index.php:
<body> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" crossorigin="anonymous"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="container-fluid"> <div class=" m-5"> <div id="chat_history" class="row"> <div class="spinner-border m-5 text-success" role="status"> <span class="sr-only">Loading...</span> </div> </div> <div id="chat_form" class=" mt-5 mr-auto ml-auto mb-5"> <form id="form_message"> <div class="form-group"> <label for="name">Name</label> <input type="text" class="form-control" placeholder="Name"> </div> <div class="form-group"> <label for="message">Message</label> <textarea class="form-control" name="message" rows="3" placeholder="your message here"></textarea> </div> <input class="btn btn-primary" type="submit" name="send" value="send"> </form> </div> </div> </div> <script> $(document).ready(function () { function updateChat() { $.ajax({ 'method': 'POST', 'dataType': 'html', 'url': 'ajax.php', 'data': 'type=chat_history', success: function (data) {//success callback $('#chat_history').text('').html(data); } }); } setInterval(updateChat, 5000); updateChat(); $('#form_message').on('submit', function (el) {//event submit form el.preventDefault();//the default action of the event will not be triggered $('#chat_form').addClass('spinner-border'); $('#form_message').hide(); var formData = $(this).serialize(); $.ajax({ 'method': 'POST', 'dataType': 'json', 'url': 'ajax.php', 'data': formData + '&type=send_message', success: function (data) {//success callback updateChat(); $('#chat_form').removeClass('spinner-border'); $('#form_message textarea[name=message]').val(''); $('#form_message').show(); } }); }); }); </script> </body>
Сообщение не промодерировано, возможны ошибки и неточности.
|
Все сделал по инструкци, но идет бесконечная загрузка на странице index.php, а именно chat_history. Почему так происходит? Коннектер успешно зареган и линия настроена. Но сообщения не приходят в ОЛ.
|
Сообщение не промодерировано, возможны ошибки и неточности.
|
||
| ||
Сообщение не промодерировано, возможны ошибки и неточности.
|
Для работы это примера и не только - не забудьте добавить локальному приложению соответствующие права, а именно:
Контакт-центр, Открытые линии, Коннекторы для внешних мессенджеров, Чат и уведомления. |
Сообщение не промодерировано, возможны ошибки и неточности.
|
||
| ||
Пользовательские комментарии
Мы будем рады, если разработчики добавят свои комментарии по практическому использованию методов системы.Для этого нужно всего лишь авторизоваться на сайте
Но помните, что Пользовательские комментарии, несмотря на модерацию, не являются официальной документацией. Ответственность за их использование несет сам пользователь.
Также Пользовательские комментарии не являются местом для обсуждения функционала. По подобным вопросам обращайтесь на форумы.