Александр Мисюрин
24.06.2019
5938

Создание переадресаций по расписанию

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

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

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

Проверку переадресации инициируем при вызове на любой внутренний номер.

Пример заполнения даты и времени можно посмотреть в базе asterisk, таблице timegroups_details.

Соответственно необходимо создать свою таблицу с необходимыми полями:

use asteriskcdrdb;
create table times (ext varchar(10) NOT NULL PRIMARY KEY, time varchar(100) NOT NULL, num varchar(25) NOT NULL);
Базу asteriskcdrdb можно не использовать, но тогда придется создавать подключение к новой базе данных через odbc.
Временные группы, пример заполнения

Для создания расписания необходимо реализовать веб-интерфейс управления, для достпа к нему создадим виртуальный хост в конфигах apache.

Listen 5445
NameVirtualHost *:5445
<VirtualHost *:5445>
        DocumentRoot /usr/src/test
		<Directory /usr/src/test>
	                Options -Indexes
	                AllowOverride All
		</Directory>
</VirtualHost>

В корне указанной директории создаем файл index.php, который будет стартовой страницей.

На странице создаем поля ввода номеров и интервала дней месяца, недели и времени, которые должны быть обязательно заполнены (required).

Предварительная форма ввода
$months = array(1 => 'jan', 2 => 'feb', 3 => 'mar', 4 => 'apr', 5 => 'may', 6 => 'jun', 7 => 'jul', 8 => 'aug', 9 => 'sep', 10 => 'oct', 11 => 'nov', 12 => 'dec');
$days = array(1 => 'mon', 2 => 'tue', 3 => 'wed', 4 => 'thu', 5 => 'fri', 6 => 'sat', 7 => 'sun');
//Массивы для имени месяца и дней недели
echo "
<form action='' method=post>
Ваш номер: <input name=ext type='text' pattern='[0-9]{3-8}' required>
Номер направления: <input name=num type='text' pattern='[0-9]{10-11}' required><br />

Месяц начало: <select name='month1'/>
<option value = '*' >-</option>";
foreach ($months as $month) {
	echo "<option value = '".$month."' >".$month."</option>";
}
echo "</select>

Месяц конец: <select name='month2'/>
<option value = '*' >-</option>";
foreach ($months as $month) {
	echo "<option value = '".$month."' >".$month."</option>";
}
echo "</select><br />

День месяца начало: <select name='day1'/>
<option value = '*' >-</option>";
for ($i=1; $i<=31; $i++) {
	echo "<option value = '".$i."' >".$i."</option>";
}
echo "</select>
День месяца конец: <select name='day2'/>
<option value = '*' >-</option>";
for ($i=1; $i<=31; $i++) {
	echo "<option value = '".$i."' >".$i."</option>";
}


echo "</select><br />
День недели начало: <select name='week1'/>
<option value = '*' >-</option>";
foreach ($days as $week) {
	echo "<option value = '".$week."' >".$week."</option>";
}
echo "</select>
День недели конец: <select name='week2'/>
<option value = '*' >-</option>";
foreach ($days as $week) {
	echo "<option value = '".$week."' >".$week."</option>";
}
echo "</select>
<br />
Время: <input name=time1 type='time' value=00:00 required> - <input name=time2 type='time' value=00:00 required><br />
<input name='interval' type=submit value=Добавить> </br>
</form>";

Реализуем обработчик нажатия (для теста можно вывести все, что отправляется через POST запрос:

if(isset($_POST['interval']))
{
	echo "<pre>".print_r($_POST,true)."</pre>";
}

Сам обработчик дополним проверкой совпадений введенных значений и пустых значений:

if ( ($_POST['time1']=='00:00') and ($_POST['time2']=='00:00') )
	{
		$time='*';
	} else $time=$_POST['time1']."-".$_POST['time2'];
	
	if ( ($_POST['week1']=='*') or ($_POST['week2']=='*') )
	{
		$week='*';
	}
	if ($_POST['week1'] == $_POST['week2']) {
		$week=$_POST['week1'];
	} else $week=$_POST['week1']."-".$_POST['week2'];
	
	if ( ($_POST['day1']=='*') or ($_POST['day2']=='*') )
	{
		$day='*';
	} else $day=$_POST['day1']."-".$_POST['day2'];
	
	if ( ($_POST['month1']=='*') or ($_POST['month2']=='*') )
	{
		$month='*';
	} 
	if ($_POST['month1'] == $_POST['month2']) {
		$month=$_POST['month1'];
	} else $month=$_POST['month1']."-".$_POST['month2'];

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

echo $time."|".$week."|".$day."|".$month;
Проверка вывода информации

Пишем и проверяем заполнение базы данных.

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

List.php:

include('/usr/src/test/connectdb.php');
echo "<form action='' method=post>
<table border=1><tr><td>Внутренний</td><td>Время срабатывания перевода</td><td>Номер направления</td><td>Удалить</td></tr>";
	$result = bd_bridge('asteriskcdrdb','SELECT ext, time, num FROM times ORDER BY ext ASC;');
	while ($row = mysqli_fetch_array($result)) 
	{
		echo "<tr>
		<td>".$row[0]."</td>
		<td>".$row[1]."</td>
		<td>".$row[2]."</td>
		<td><input type='checkbox' name='temp_arr[]' value='$row[0]' id='$row[0]' class='checkbox' /></td>
		</tr>";
	}
	echo "
	</table>
	<input name='delete' type=submit value=Удалить> </br>
	</form>";

Вывод списка текущих переадресаций, добавим обработчик удаления из списка и конпку возврата на страницу добавления:

if(isset($_POST['delete']))
{
	//echo "<pre>".print_r($_POST,true)."</pre>";
	foreach ($_POST[temp_arr] as $value){
		//echo "Удалено";
		$request = mysqli_fetch_array(bd_bridge("asteriskcdrdb","DELETE FROM times WHERE ext='".$value."';"));
		echo "<script language='JavaScript' type='text/javascript'>window.location.replace('list.php')</script>";
	}
}

echo "
<form action='index.php' method='post'><table>
<input type='submit' value='Начало'>
</form>
";

Функция bd_bridge:

function bd_bridge($db,$q){
                $link = @mysqli_connect('localhost','freepbxuser','freepbxpass',$db) or die("Error: ".@mysqli_connect_error($link));
                $rs = @mysqli_query($link, $q) or die("Error: ".@mysqli_error($link));
                if($rs){
                        //echo "Qwerty complete: $q <br />";
                        return $rs;
                        @mysqli_free_result($rs);
                }
                else{
                        //echo "Qwerty failure: $q <br />";
                }
                mysqli_close($link);
        }
Обработчик вызова реализуем через диалплан, в данном случае используем контекст from-internal-custom.

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

exten => _XXX,1,Set(cftime=${ODBC_СFTIMES()})
same => n,Set(cftime=${REPLACE(cftime,|,,)})
same => n,Set(cfnum=${ODBC_CFNUM()})
same => n,GotoIf($["${cftime}" = ""]?from-internal-additional,${EXTEN},1)
same => n,GotoIfTime(${cftime}?from-internal-additional,${cfnum},1:ext-local,${EXTEN},1)
same => n,Macro(hangupcall,)

Соответственно сами функции:

[CFTIMES]
dsn=asteriskcdrdb
readsql=select time from times where ext='${EXTEN}' LIMIT 1;

[CFNUM]
dsn=asteriskcdrdb
readsql=select num from times where ext='${EXTEN}' LIMIT 1;
Стоит учесть, что дальнейшее направление на внутренний номер, должно выполняться из контекста, в который не включен from-internal-custom, например ext-local (либо другие контексты, если вы используете версию без FreePBX).

Проверяем добавление и переадресации:

Проверка
Подписаться
Уведомить о
guest
2 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
Александр
Александр
15.04.2021 20:03

Доброго дня.
Моя конфигурация астериск немного отличается от всех шаблонных, хотя бы тем, что я использую postgres.
Я плохо разбираюсь в PHP поэтому вопрос:
Можете выложить полностью листинг всех PHP фалов для данного «модуля» подкорректировать я смогу и самостоятельно?

Александр
Александр
29.04.2021 12:33
Ответить на  Александр

Добрый день, тут весь код, просто он представлен по порядку частями. Может только за исключением служебных тегов («<php», «?>»,…)

Остались вопросы?

Я - Виталий Шелест, менеджер компании Voxlink. Хотите уточнить детали или готовы оставить заявку? Укажите номер телефона, я перезвоню в течение 3-х секунд.

VoIP оборудование


ближайшие курсы

10 доводов в пользу Asterisk

Распространяется бесплатно.

Asterisk – программное обеспечение с открытым исходным кодом, распространяется по лицензии GPL. Следовательно, установив один раз Asterisk вам не придется дополнительно платить за новых абонентов, подключение новых транков, расширение функционала и прочие лицензии. Это приближает стоимость владения станцией к нулю.

Безопасен в использовании.

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

Надежен в эксплуатации.

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

Гибкий в настройке.

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

Имеет огромный функционал.

Во многом именно Asterisk показал какой должна быть современная телефонная станция. За многие годы развития функциональность Asterisk расширилась, а все основные возможности по-прежнему доступны бесплатно сразу после установки.

Интегрируется с любыми системами.

То, что Asterisk не умеет сам, он позволяет реализовать за счет интеграции. Это могут быть интеграции с коммерческими телефонными станциями, CRM, ERP системами, биллингом, сервисами колл-трекинга, колл-бэка и модулями статистики и аналитики.

Позволяет телефонизировать офис за считанные часы.

В нашей практике были проекты, реализованные за один рабочий день. Это значит, что утром к нам обращался клиент, а уже через несколько часов он пользовался новой IP-АТС. Безусловно, такая скорость редкость, ведь АТС – инструмент зарабатывания денег для многих компаний и спешка во внедрении не уместна. Но в случае острой необходимости Asterisk готов к быстрому старту.

Отличная масштабируемость.

Очень утомительно постоянно возвращаться к одному и тому же вопросу. Такое часто бывает в случае некачественного исполнения работ или выбора заведомо неподходящего бизнес-решения. С Asterisk точно не будет такой проблемы! Телефонная станция, построенная на Asterisk может быть масштабируема до немыслимых размеров. Главное – правильно подобрать оборудование.

Повышает управляемость бизнеса.

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

Снижает расходы на связь.

Связь между внутренними абонентами IP-АТС бесплатна всегда, независимо от их географического расположения. Также к Asterisk можно подключить любых операторов телефонии, в том числе GSM сим-карты и настроить маршрутизацию вызовов по наиболее выгодному тарифу. Всё это позволяет экономить с первых минут пользования станцией.