Документация для разработчиков
Темная тема

Пример коннектора Открытых линий для онлайн-чата на сайте

Внимание! Пример заработает только на локальном приложении, в случае использования вебхуков он не сработает.

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

  1. После установки всех файлов, запускаем через браузер файл install_connector.php для первоначальной настройки ОЛ. При успешной первоначальной настройке у вас отобразится надпись successfully.
  2. Открыть раздел с открытыми линиями и там находим блок с названием "ExampleSiteChat".
  3. Открыв раздел с "ExampleSiteChat" нажимаем кнопку "подключить".
  4. Если вы всё верно настроили вам выдаст также надпись successfully.
  5. Установка закончена, вы можете открыть файл index.php и начать первый диалог в чате.

Внимание! Для использования данного примера необходимо настроить работу класса CRest и подключить файл crest.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>



© «Битрикс», 2001-2024, «1С-Битрикс», 2024