Алина Леонова
25.06.2020
3005

Отправка статистики из Asterisk на почту и в ВКонтакте

В данной статье рассмотрим возможность отправки небольшой статистики из CDR на почту или в ВКонтакте. Задача: необходимо собрать в файл.csv следующую статистику: дата вызова, кто звонил, кто ответил (если отвечено), время вызова и статус звонка. Данную статистику отправить на почту или в ВКонтакте по звонку на сервисный код. Также отправлять информацию по входящим/исходящим вызовам, если […]

В данной статье рассмотрим возможность отправки небольшой статистики из CDR на почту или в ВКонтакте.

Задача: необходимо собрать в файл.csv следующую статистику: дата вызова, кто звонил, кто ответил (если отвечено), время вызова и статус звонка. Данную статистику отправить на почту или в ВКонтакте по звонку на сервисный код. Также отправлять информацию по входящим/исходящим вызовам, если известен номер, на который нужна данная статистика.

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

Написание скрипта

Актуально для php версии 5.6

<?php
	date_default_timezone_set('Europe/Moscow');
	$dsn = 'mysql:host=localhost; dbname=asteriskcdrdb';
	$user = 'пользователь mysql';
	$pass = 'пароль от пользователя mysql;
	$time = mktime();
	try {
		$dbh = new PDO($dsn, $user, $pass);
	} catch (PDOException $e) {
		die ('При подключении к базе данных возникла ошибка.' . $e->getMessage()); 
	}
	$status = isset($argv[1]) ? $argv[1] : "";
	$number = isset($argv[2]) ? $argv[2] : "";
	if($status == 'all'){
		$query_all = "SELECT calldate, src, dst, duration, disposition FROM cdr WHERE calldate >= DATE_SUB(CURDATE(),INTERVAL 1 WEEK)";
		$res = $dbh->query($query_all);
		$result = $res->fetchAll(PDO::FETCH_ASSOC);
		SaveStat($result, $status, $time);
	}else if($status == 'outbound'){
		$query_outbound = "SELECT calldate, src, dst, duration, disposition FROM cdr WHERE calldate >= DATE_SUB(CURDATE(),INTERVAL 1 WEEK) AND src = :number";
		$res = $dbh->prepare($query_outbound);
		$res->execute(array("number" => $number));
		$result = $res->fetchAll(PDO::FETCH_ASSOC);
		SaveStat($result, $status, $time);
	}else if($status == 'inbound'){
		$query_outbound = "SELECT calldate, src, dst, duration, disposition FROM cdr WHERE calldate >= DATE_SUB(CURDATE(),INTERVAL 1 WEEK) AND dst = :number";
		$res = $dbh->prepare($query_outbound);
		$res->execute(array("number" => $number));
		$result = $res->fetchAll(PDO::FETCH_ASSOC);
		SaveStat($result, $status, $time);
	}else{
		die("Не найден искомый тип");
	}
function SaveStat($stat_list, $status, $time){
		$fcsv = fopen("/var/www/html/save_stat/fields/".$status."_week_".$time.".csv", "w");
		foreach ($stat_list as $stat_row) {
			$list = array();
			foreach ($stat_row as $row) {
				array_push($list, $row); 
			}
			fputcsv($fcsv, $list);
		}
		fclose($fcsv);
	}
?>

Подробнее остановимся на том, что написали в скрипте. Определяем таймзону, прописываем необходимые переменные и подключаемся к базе. Таймзону определяем для того, чтобы корректно отработала функция mktime – она же нужна в данном скрипте для имени файла. С помощью неё, если за статистикой обратится, к примеру, 2 человека одновременно, ни один из файлов не будет перезаписан.

Также в переменные $status и $number в дальнейшем из диалплана будут переданы такие аргументы, как тип статистики и номер (либо src, либо dst). Сразу же проверяем эти переменные на пустоту. Далее выполняем условия:

  1. Если тип статистики равен all – выполняем запрос в базу данных. В примере этот запрос должен вывести даты вызовов, кто звонил, куда звонил, время вызовов, а также отвечены они или нет. Вывод происходит за неделю от текущей даты. После получения вывода запроса, вызываем функцию SaveStat. В неё передаём вывод, тип статистики и время в UNIX-формате.
  2. Для типов outbound или inbound выполняется то же самое, что и в all, за исключением того, что в запрос теперь будет добавлен явный номер, для которого собираем статистику по, соответственно, исходящим или входящим направлениям.
  3. Также, при неизвестном переданном типе, вернём: «Не найден искомый тип».

Теперь рассмотрим функцию SaveStat. В ней открываем файл.csv. Далее берём все нужные значения из массива и экспортируем их. После этого файл закрываем.

На этом шаге перейдём к диалплану.

Составление диалплана

Здесь важно определить структуру того, что нужно сделать. В примере вызов будет происходить на кастомный сервисный код. Здесь сделаем небольшую IVR – общую статистику собираем по нажатию 1, статистику по исходящим – 2, статистику по входящим – 3. При нажатии 2 или 3 также даём возможность до набрать номер, на который необходима статистика. Затем нужно будет вызывать скрипт stat.php и передавать ему нужный тип статистики.

[from-internal-custom]
exten => *3700,1,NoOp("Выгрузка статистики")
same  => n,Answer()
same  => n,Playback(/var/lib/asterisk/sounds/ru/custom/save)
same  => n,WaitExten(10)
exten => 1,1,NoOp("Общая статистика")
same  => n,System(php -f /var/www/html/save_stat/stat.php all)
same  => n,Playback(/var/lib/asterisk/sounds/ru/beep)
same  => n,Hangup()
same  => n,WaitExten(10)
exten => 2,1,NoOp("Исходящая вызовы с номера num")
same  => n,Playback(/var/lib/asterisk/sounds/ru/custom/num)
same  => n,Set(TOUCH=2)
same  => n,WaitExten(10)
exten => 3,1,NoOp("Входящие вызовы на номер num")
same  => n,Playback(/var/lib/asterisk/sounds/ru/custom/num)
same  => n,Set(TOUCH=3)
same  => n,WaitExten(10)
exten => _X.,1,NoOp("Num")
same  => n,ExecIf($[${TOUCH} = 2]?System(php -f /var/www/html/save_stat/stat.php outbound):System(php -f /var/www/html/save_stat/stat.php inbound))
same  => n,Playback(/var/lib/asterisk/sounds/ru/beep)
same  => n,Hangup()

Отправка статистики на почту

Для того, чтобы отправить статистику на почту, дополним скрипт следующими переменными: $email = ‘имя отправителя’ и $email_to = ‘имя получателя’. Также до вызова функции допишем следующий код:

`/usr/local/bin/sendEmail.pl -f {$email} -t {$email_to} -u "Файл статистики" -m "Файл во вложении к письму." -a /var/www/html/save_stat/fields/{$status}_week_{$time}.csv -o message-charset=utf-8`;
`rm -f /var/www/html/save_stat/fields/{$status}_week_{$time}.csv`;

С помощью первой строки отправим сообщение с файлом статистики на почту получателя, а с помощью второй строки после этого удалим файл с сервера.

Теперь сделаем тестовый вызов на сервисный код *3700.

Лог вызова

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

Пришедшее сообщение

Отправка статистики в ВКонтакте

Подробнее о том, как настроить связку между ВКонтакте и Asterisk можно прочитать в этой статье.

Отправляемый файл не должен превышать 200МБ.

Отправку файла статистики будем производить в 4 шага:

Получение URL для загрузки

Сначала объявим необходимые на этом шаге переменные:

$id_to = 'ID получателя';
$url_server_to = 'https://api.vk.com/method/docs.getMessagesUploadServer';
$key = 'ключ доступа к сообществу'.
У ключа доступа должны быть права на сообщения и документы сообщества.

Далее сформируем массив со всеми нужными данными:

$data = array(
	'v' => '5.107',
	'access_token' => $key,
	'peer_id' => $id_to,
	'type' => 'doc',
	);

Кроме ключа доступа и ID получателя, здесь также содержится информация о версии API и тип файла, который будем загружать.

Вызываем функцию ReceiveURL, в которую будет переданы массив данных ($data) и URL ($url_server_to), который вернёт необходимую ссылку, по которой будем загружать файл на сервер.

$res = ReceiveURL($data, $url_server_to);
$res = json_decode($res, true);
$url_doc = $res["response"]["upload_url"];

Результат будет возвращён в JSON-формате, поэтому его необходимо будет распарсить. Затем, из полученного массива берём upload_url, который вложен в response, и помещаем в переменную $url_doc.

Теперь перейдём к описанию функции ReceiveURL.

function ReceiveURL($data, $url_server_to){
	$ch = curl_init();
	$par = http_build_query($data, '', '&');
	curl_setopt($ch, CURLOPT_URL, $url_server_to . "?$par");
	curl_setopt($ch, CURLOPT_HEADER, false);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	$res = curl_exec($ch);
	return $res;
}

Здесь формируем ссылку типа: «https://api.vk.com/method/docs.getMessagesUploadServer?v=$data[‘v’]&access_token=$data[‘access_token’]&peer_id=$data[‘peer_id’]&type=$data[‘type’]». В результате возвращаем ссылку на сервер, куда будем загружать файл.

Загрузка файла в ВКонтакте

Cначала произведём вызов функции UploadURL.

$res = UploadURL($url_doc, $status, $time);
$res = json_decode($res, true);
$file_up = $res["file"];

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

Опишем функцию UploadURL.

function UploadURL($url_doc, $status, $time){
	$ch = curl_init($url_doc);
	$doc_file = curl_file_create("/var/www/html/save_stat/fields/".$status."_week_".$time.".csv");
	$file_arr = array('file' => $doc_file);
	curl_setopt($ch, CURLOPT_POST, 1);
	curl_setopt($ch, CURLOPT_POSTFIELDS, $file_arr);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	$res = curl_exec($ch);
	return $res;
}

 В данной функции из файла статистики формируем CURL-файл ($doc_file) и загружаем его по ранее полученной ссылке ($doc_file). В результате получаем информацию, необходимую для сохранения файла в ВКонтакте.

Сохранение файла в ВКонтакте

На этом шаге снова понадобится объявить переменную:

$url_server_save = ‘https://api.vk.com/method/docs.save’ – ссылка для сохранения документа в ВКонтакте.

Теперь перейдём к вызову функции SaveFile.

$res = SaveFile($file_up, $url_server_save, $data, $status, $time);
$res = json_decode($res, true);
$file_id = $res["response"]["doc"]["id"];
$file_owner_id = $res["response"]["doc"]["owner_id"];

При вызове функции SaveFile передаём в неё следующие аргументы: CURL-файл, полученный ранее, ссылку для сохранения файла, объявленную на этом шаге. Также сюда передаём массив данных ($data), тип статистики ($status) и время ($time). Результат будет возвращён в JSON-формате. Из полученного массива нужно будет взять тип и ID файла, которые вложены в response. Эту часть помещаем в переменную $file_id. Также нужно будет взять тип и ID владельца файла, которые вложены в response – эту часть помещаем в $file_owner_id.

Переходим к описанию функции SaveFile.

function SaveFile($file_up, $url_server_save, $data, $status, $time){
	$ch = curl_init();
	$data["file"] = $file_up;
	$data["title"] = $status."_week_".$time.".csv";
	$data["tags"] = "";
	$par = http_build_query($data, '', '&');
	curl_setopt($ch, CURLOPT_URL, $url_server_save . "?$par");
	curl_setopt($ch, CURLOPT_HEADER, false);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	$res = curl_exec($ch);
	return $res;	
}

В данной функции также к массиву данных $data передаём следующие аргументы:

$data[‘file’] – информация о файле;

$data[‘title’] – имя файла;

$data[‘tags’] – метки для поиска.

Метки для поиска могут быть пустыми, как в примере.

Затем формируем ссылку типа: «https://api.vk.com/method/docs.save? v=$data[‘v’]&access_token=$data[‘access_token’]&peer_id=$data[‘peer_id’]&type=$data[‘type’]&file=$data[‘file’]&title=$data[‘title’]&tafs=$data[‘tags’]».

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

Отправка файла

На этом шаге нужно объявить:

$text = 'Во вложении файл статистики.';
$url = 'https://api.vk.com/method/messages.send';
$data_file = array(
	'v' => '5.37',
	'access_token' => $key,
	'message' => $text,
	'user_id' => $id_to,
);

Здесь в переменной $text будет содержаться текст сообщения, которое придёт в ВКонтакте, а в массиве данных передаём версию API, ключ доступа, текст сообщения и ID получателя.

$data_file['attachment'] = 'doc'.$file_owner_id.'_'.$file_id;
$res = SendVKFile($data_file, $url);

Перед вызовом функции к массиву $date_file передаём в качестве ещё одного важного элемента attachment, в котором будет содержаться тип файла, ID владельца файла и ID получателя. При вызове функции передаём в неё массив данных ($data_file) и объявленный на текущем шаге $url.

Опишем функцию SendVKFile.

function SendVKFile($data_file, $url){
	$ch = curl_init();
	$par = http_build_query($data_file, '', '&');
	curl_setopt($ch, CURLOPT_URL, $url . "?$par");
	curl_setopt($ch, CURLOPT_HEADER, false);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	$res = curl_exec($ch);
	echo $res."\n";
	return $res;
}

Сначала формируем ссылку для отправки сообщения. Она будет выглядеть следующим образом:

«https://api.vk.com/method/messages.send?v=$data_file[‘v’]&access_tocken=$data_file[‘access_token’]&message=$data_file[‘message’]&user_id=$datra_file[‘user_id’]&attachment=$data_file[‘attachment’]».

Именно по этой ссылке будет происходить отправка сообщения с файлом статистики.

Проверим, позвонив на *3700. После того, как вызов будет завершён, в ВКонтакте увидим пришедшее сообщение с файлом статистики.

Пришедшее сообщение в ВКонтакте

На этом статья по отправке файла статистики на почту и в ВКонтакте завершена.

Подписаться
Уведомление о
guest
0 Комментарий
Inline Feedbacks
View all comments

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

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

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

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

ближайшие Вебинары

ONLINE

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 сим-карты и настроить маршрутизацию вызовов по наиболее выгодному тарифу. Всё это позволяет экономить с первых минут пользования станцией.