Архив метки: Asterisk

FreePBX, Elastix. Уведомление о пропущенных вызовах

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

Уведомления при потерянных вызовах на IVR

Если вызовы поступают на IVR, и звонящий не дождавшись ответа положил трубку, то для отчетов правим файл /etc/asterisk/extensions_override_freepbx.conf

# nano /etc/asterisk/extensions_override_freepbx.conf

 

[ivr-1] ;Номер ivr

exten => h,1,System(python /usr/local/bin/sendmail.py "Пропущенный вызов в ${STRFTIME(${EPOCH},,%Y-%m-%d %H:%M:%S)}с номера ${CALLERID(name)}")


Сохраняем и делаем reload астериска. Тепер. если позвонивший положит трубку слушая голосовое меню, то на почту прийдет уведомление. Сам  sendmail.py находится в конце статьи.

Уведомление в группах вызова

Если необходимо уведомлять о потерянных вызовах в группах вызова, то также правим файл /etc/asterisk/extensions_override_freepbx.conf

# nano /etc/asterisk/extensions_override_freepbx.conf

 

[ext-group]

exten => h,1,System(python /usr/local/bin/sendmail.py "Пропущенный вызов в ${STRFTIME(${EPOCH},,%Y-%m-%d %H:%M:%S)}с номера ${CALLERID(name)}")

exten => h,2,Macro(hangupcall,)

 Уведомление в очередях

Если же вызов поступает в очередь, то в /etc/asterisk/extensions_override_freepbx.conf  прописываем

[ext-queues]

exten => h,1,ExecIf($["${CDR(dstchannel)}"=""]?System(python /usr/local/bin/sendmail.py "Пропущенный вызов в ${STRFTIME(${EPOCH},,%Y-%m-%d %H:%M:%S)} с номера ${CALLERID(name)}"))

exten => h,2,Macro(hangupcall,)

Сам файл sendmail.py

#!/usr/bin/python

# -*- coding: utf-8 -*-

from email.MIMEText import MIMEText

import smtplib

import sys

sender = 'noanswer@yourdomain.ru' # От кого

recivers = 'youremail' # Ваш e-mail

host = "localhost"

text = sys.argv[1]

msg = MIMEText(text, "", "utf-8")

msg["Subject"] = "Уведомление о пропущенном вызове"

smtpObj = smtplib.SMTP('localhost')

smtpObj.sendmail(sender, recivers, msg.as_string())

smtpObj.close()


Не забудте дать права на запуск

chmod 755 /usr/local/bin/sendmail.py



2018-09-29T23:30:16
Asterisk

Asetrisk, распознавание и генерации речи с помощью yandex speechkit

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

Итак, настройка Asterisk, для простоты настраивать будем через ael:

На Астериске организован цикл while

1234567 => {

Answer;

Set(audio=/var/lib/asterisk/sounds/custom/enteraccount);

flag=1;

label=1;

while (${flag} = 1){

Background(${audio});

Record(/tmp/${UNIQUEID}label${label}.wav,3,20);

Agi(yandex.agi,/tmp/${UNIQUEID}, ${label});

label=${label}+1;



                  };



    };

В начале позвонившему проигрывается фудио файл «enteraccount» с просьбой назвать лицевой счет

На каждом шаге цикла, позвонившему человеку проигрывается аудио файл «audio», путь к которому получен из agi скрипта, далее записывается ответ, и путь к полученному записанному файлу отправляется agi скрипту, также в скрипт отправляется текущий шаг «label», после чего шаг увеличивается на 1, и цикл повторяется. Из agi скрипта астерис получает 2 параметра, это обязательный параметр «audio», путь к аудиофайлу который нужно проиграть, и не обязательный «label», метка с помощью которой происходит синхронизация астериска и agi. Выход из цикла происходит если человек положил трубку, а также если из agi прийдет параметр «flag» не равный 1.

Еще неплохо бы после завершения вызова удалить все временные файлы, для этого в макросе который срабатывает после завершения вызова пропишем

[macro-hangupcall]

exten => s,1,System(find /tmp/ -name "${UNIQUEID}*" | xargs rm);

На этом настройка астериска завершена.

Далее сам скрипт yandex.agi, написанный на python, для работы необходимо установить pyst

# wget http://heanet.dl.sourceforge.net/project/pyst/pyst/0.6.50/pyst-0.6.50.zip

# unzip pyst-0.6.50.zip

# cd pyst-0.6.50

# python setup.py install

Сам agi:

#!/usr/bin/python

# -*- coding: utf-8 -*-

import urllib2

import urllib

import sys

import random

from xml.dom.minidom import *

import os

import asterisk.agi



agi=asterisk.agi.AGI()

uuid=''

key='28b22b47-a7b0-40d2-892d-ad79bbdbc304'

def yadexASR(uuid, key, topic, callid):

# Функция для преобразования аудио файла в текст

# Генерим уникальный код id для запроса

    while (len(uuid)<32):

        uuid=uuid+random.choice('1234567890abcdef')

    #Ссылка для пост запроса 

    url = 'https://asr.yandex.net/asr_xml?uuid=%s&key=%s&topic=%s&lang=ru-RU' % (uuid, key, topic)

    filename = callid+'.wav'

    #Считываем файл в двоичном режиме

    audio = open(filename,'rb').read()

    #Указываем тип аудиофайла для заголовка в POST запрос

    headers={'Content-Type': 'audio/x-pcm;bit=16;rate=8000'}

    #Отправляем запрос

    request = urllib2.Request(url, data=audio, headers=headers)

    response = urllib2.urlopen(request)

    #Считываем ответ

    answer=response.read()

    # Создаем xml файл для полученного ответа

    f_answer=('%s.xml' % callid)

    f=open(f_answer, 'w')

    # записываем в файл ответ полученный на POST запрос (ответ получен в xml формате)

    f.write(answer)

    f.close()

    # Парсим xml файл

    xml = parse(f_answer)

    # Выбираем из файла значение между тегами variant

    var = xml.getElementsByTagName('variant')

    # Выбираем первое значение из xml файла, оно же наиболее точное в распознании

    result=var[0].childNodes[0].nodeValue

    return result



def generate(key,text, file):

# Функция для преобразования текста в аудио формат

    #Форматируем текс для GET запрса (нужен для корректной обработки кирилици)

    text_f=urllib.quote_plus(text.encode('utf-8'))

    #отправляем запрос на яндекс

    url='http://tts.voicetech.yandex.net/generate?text=%s&format=mp3&lang=ru-RU&speaker=jane&key=%s' % (text_f, key)

    # Сохраняем айдио файл в file

    urllib.urlretrieve(url, file)



if sys.argv[2].replace(' ','')=="1":

    agi.verbose('label='+sys.argv[2].replace(' ',''))

    try:

        # Распознаем полученный файл

        result=yadexASR(uuid, key, 'notes', sys.argv[1]+'label'+sys.argv[2].replace(' ',''))

        # Формируем ответ

        file=sys.argv[1]+'outlabel'+sys.argv[2].replace(' ','')

        generate(key, u'Вы сказали '+result+u'Скажите да или Нет', file+'.mp3')

        agi.set_variable('audio', file)

    except:

        agi.set_variable('audio', '/var/lib/asterisk/sounds/custom/enteraccount')

        agi.set_variable('label', '0')

        agi.verbose('label=0')



elif sys.argv[2].replace(' ','')=="2":

    agi.verbose('label='+sys.argv[2].replace(' ',''))

    try:

        result=yadexASR(uuid, key, 'notes', sys.argv[1]+'label'+sys.argv[2].replace(' ',''))

    except:

        agi.set_variable('label', '1')

    if 'Да' in str(result.encode('utf-8')):

        agi.verbose('Yes')

        #///////////////////////////////

        # Здест должна быть проверка на существование абонента в базе данных

        #/////////////////////////////

    

        file=sys.argv[1]+'outlabel'+sys.argv[2].replace(' ','')

        generate(key, u'Показания какого счетчика вы хотите сообщить горячего или холодного?', file+'.mp3')

        agi.set_variable('audio', file)

    elif 'Нет' in str(result.encode('utf-8')):

        agi.verbose('No')

        # Ставим метку в 0 что бы вернуться к шагй 1 и проигрываем файл

        agi.set_variable('label', '0')

        agi.set_variable('audio', '/var/lib/asterisk/sounds/custom/enteraccount')

    else:

        agi.verbose('Error')

        # Если ответ не да и ни нет, говорим об ошибки и ставим метку на 1 что бы вернуться к шагу 2

        agi.set_variable('label', '1')

elif sys.argv[2].replace(' ','')=="3":

    agi.verbose('label='+sys.argv[2].replace(' ',''))

    try:

        result=yadexASR(uuid, key, 'notes', sys.argv[1]+'label'+sys.argv[2].replace(' ',''))

    except:

        agi.set_variable('label', '2')

    if 'Горяч' in str(result.encode('utf-8')):

        agi.verbose('Hot')      

        file=sys.argv[1]+'outlabel'+sys.argv[2].replace(' ','')

        generate(key, u'Сообщите показания горячего счетчика', file+'.mp3')

        agi.set_variable('audio', file)

    elif 'Холод' in str(result.encode('utf-8')):

        agi.verbose('Cold')     

        file=sys.argv[1]+'outlabel'+sys.argv[2].replace(' ','')

        generate(key, u'Сообщите показания холодного счетчика', file+'.mp3')

        agi.set_variable('audio', file)

    else:

        agi.verbose('Error')

        agi.set_variable('label', '2')

elif sys.argv[2].replace(' ','')=="4":

    agi.verbose('label='+sys.argv[2].replace(' ',''))

    try:

        result=yadexASR(uuid, key, 'notes', sys.argv[1]+'label'+sys.argv[2].replace(' ',''))      

        file=sys.argv[1]+'outlabel'+sys.argv[2].replace(' ','')

        generate(key, u'Ваши показания '+result+u'Скажите да или Нет', file+'.mp3')

        agi.set_variable('audio', file)

    except:

        agi.set_variable('label', '3')

        agi.verbose('label=3')

elif sys.argv[2].replace(' ','')=="5":

    try:

        result=yadexASR(uuid, key, 'notes', sys.argv[1]+'label'+sys.argv[2].replace(' ',''))

    except:

        agi.set_variable('label', '1')

    if 'Да' in str(result.encode('utf-8')):

        

        #/////////////

        #Обрабатываем результат и заносим в базу

        #/////////////

 

        file=sys.argv[1]+'outlabel'+sys.argv[2].replace(' ','')

        generate(key, u'Хотите сообщить показания другого счетчика да или нет?', file+'.mp3')

        agi.set_variable('audio', file)

    elif 'Нет' in str(result.encode('utf-8')):

        agi.set_variable('label', '2')

        file=sys.argv[1]+'outlabel'+sys.argv[2].replace(' ','')

        generate(key, u'Показания какого счетчика вы хотите сообщить горячего или холодного?', file+'.mp3')

        agi.set_variable('audio', file)

    else:

        agi.verbose('Error')

        agi.set_variable('label', '2')

elif sys.argv[2].replace(' ','')=="6":

    try:

        result=yadexASR(uuid, key, 'notes', sys.argv[1]+'label'+sys.argv[2].replace(' ',''))

    except:

        agi.set_variable('label', '1')

    if 'Да' in str(result.encode('utf-8')):

        file=sys.argv[1]+'outlabel'+sys.argv[2].replace(' ','')

        generate(key, u'Показания какого счетчика вы хотите сообщить горячего или холодного?', file+'.mp3')

        agi.set_variable('audio', file)

        agi.set_variable('label', '2')

    elif 'Нет' in str(result.encode('utf-8')):

        file=sys.argv[1]+'outlabel'+sys.argv[2].replace(' ','')

        generate(key, u'Досвидания', file+'.mp3')

        agi.set_variable('audio', file)

    else:

        agi.verbose('Error')

        file=sys.argv[1]+'outlabel'+sys.argv[2].replace(' ','')

        generate(key, u'Хотите сообщить показания другого счетчика да или нет', file+'.mp3')

        agi.set_variable('label', '5')



2018-09-29T23:27:08
Asterisk

Elastix, права на прослушивание записей и просмотр статистики звонков

По умолчанию прослушивать запись и просматривать статистику всех звонков в Elastix может только пользователь admin, все остальные пользователи могут прослушивать и просматривать статистику только своих звонков. Если же нужно разрешить пользователю из группы Operator доступ ко всем звонкам, но при этом не делать его администратором, то в Elastix, в файле:

var/www/html/libs/paloSantoACL.class.php

В функции:

function isUserAdministratorGroup($username)

после строчки:

 $is = array_search('1', $arrGroup);

Добавить следующий код:

if(isset($arrGroup['Operator']))

$is=true;


После этого все пользователи группы Operator смогут просматривать отчет по всем звонкам, а также прослушивать все разговоры.



2018-09-29T23:25:09
Asterisk

Сброс пароля Elastix на web интерфейс

Если в качестве IP PBx вы используете Elastix, и забыли пароль на доступ по WEB интерфейсу. Есть простой способ сменить пароль администратора на WEB интерфейс, для этого у вас должен быть root доступ на консоль. Для изменения пароля на пароль по умолчанию «palosanto» нужно в консоли выполнить следующую команду:

sqlite3 /var/www/db/acl.db "update acl_user set md5_password='7a5210c173ea40c03205a5de7dcd4cb0' where id=1"

На Elastix 3.0, вышеописанная инструкция не работает. Сменить пароль можно командой

/usr/bin/elastix-admin-passwords --change

Ну и не забываем что теперь пользователь у нас superadmin и у пароля есть большие ограничения по сложности (не менее 10 разнокалиберных символов и цифр).



2018-09-28T12:32:17
Asterisk

Asterisk CDR – запись в базу данных MySQL через cdr_mysql

Причины записи CDR в базу данных MySQL

В первую очередь возникает вопрос – зачем вообще нужно записывать CDR в базу данных MySQL сервера? Дело в том, что в отличие от многих других баз, asterisk может делать запись в mysql собственными средствами, без дополнительных программ. Кроме того, установка и настройка баз MySQL является простой операцией, а сама распространенность баз данных MySQL дает возможность рекомендовать этот формат баз данных для хранения статистики звонков – CDR.+

Этапы настройки записи CDR в MySQL

Настройка сохранения истории звонков asterisk (CDR) в базу данных формата MySQL состоит из двух частей, каждая из которых состоит из нескольких этапов. Части могут настраиваться независимо и параллельно (до определенного момента).

Часть 1. Установите и настройте MySQL сервер

  1. Установите MySQL сервер
  2. Создайте базу данных для asterisk
  3. Создайте таблицу для asterisk

Часть 2 – настройка asterisk

  1. Установите компоненты для работы с MySQL: MySQL client и библиотеку для поддержки MySQL
  2. Пересоберите asterisk для работы с MySQL – cdr_mysql
  3. К этому моменту должна быть выполнена часть 1.
  4. Проверьте подключение к MySQL Server
  5. Настройте asterisk для работы с MySQL

И отдельным пунктом вынесены возможные ошибки, возникающие в процессе настройки MySQL / asterisk.

Установка и настройка MySQL

Установка MySQL Server

Для установки сервера MySQL в Debian достаточно набрать команду:

apt-get install mysql-server

В операционной системе RHEL / CentOS также все довольно просто:

yum install mysql-server

При этом будет установлена текущая (актуальная) версия mysql сервера (на момент написания статьи это версия 5.5).

В процессе установки будет необходимо задать пароль пользователя root для mysql. Не забудьте этот пароль, он Вам еще понадобится!

Для установки и первоначальной настройки MySQL сервера Вы можете воспользоваться статьей “Установка и первоначальная настройка MySQL в linux“.

Запуск сервиса MySQL

Для запуска сервиса в CentOS выполните команду:

service mysqld start

Подключение к серверу SQL для выполнения запросов

Для подключения к MySQL серверу (чтобы можно было выполнять команды SQL) Вы можете воспользоваться любыми своими имеющимися инструментами, например PHPMyAdmin. Либо же можете воспользоваться встроенными средствами командной строки из пакета MySQL – mysql:

mysql -u имя-пользователя-SQL -p

например:

mysql -u root -p

после нажатия Enter будет запрошен пароль для пользователя. После ввода пароля и нажатия Enter, будет выведено приглашение MySQL:

mysql>_

Теперь Вы можете выполнять запросы SQL.

Создание базы данных (и пользователя этой базы данных) для asterisk cdr

Для создания базы данных (назовем ее asteriskcdr, Вы можете выбрать любое другое имя) выполните команду SQL:

CREATE DATABASE asteriskcdr ;

Если Вы хотите создать отдельного пользователя (например, asterisk_user) для работы с этой базой данных, при этом выставить ему пароль например, asterisk_password, выполните команду SQL:

CREATE USER asterisk_user IDENTIFIED BY 'asterisk_password';

Теперь Вам необходимо назначить этому вновь созданному пользователю asterisk_user права для доступа к базе данных (например, права только для добавления / обновления записей и для просмотра базы). Для этого выполните команду SQL:

GRANT INSERT, SELECT, UPDATE

ON asteriskcdr.*

TO asterisk_user@localhost;

Если же Вы хотите дать этому пользователю полные права на базу данных, вместо предыдущей команды выполните эту команду SQL:

GRANT ALL

ON asteriskcdr.*

TO asterisk_user@localhost;

Если Вы хотите, чтобы пользователь MySQL мог подключаться удаленно к серверу MySQL (с другого компьютера), то (при создании, а также предоставлении ему прав доступа к БД) его имя следует указывать в формате:

имя-пользователя@хост

например:

asterisk_user@192.168.1.1

Если же Вы не знаете, с каких IP будет подключаться пользователь, либо Вам необходимо, чтобы он подключался с любых IP адресов, укажите имя пользователя в следующем формате:

имя-пользователя@’%’

например:

asterisk_user@’%’

В этом случае команда для предоставления полных прав [на работу с MySQL] пользователю asterisk_user, который может подключаться к MySQL с любых IP адресов, будет выглядеть так:

GRANT ALL

ON asteriskcdr.*

TO asterisk_user@'%';

Создание таблицы для asterisk

Для создания таблицы asterisk CDR подключитесь к созданной базе данных и выполните следующий запрос:

USE asteriskcdr;



CREATE TABLE cdr (

 calldate datetime NOT NULL default '0000-00-00 00:00:00',

 clid varchar(80) NOT NULL default '',

 src varchar(80) NOT NULL default '',

 dst varchar(80) NOT NULL default '',

 dcontext varchar(80) NOT NULL default '',

 channel varchar(80) NOT NULL default '',

 dstchannel varchar(80) NOT NULL default '',

 lastapp varchar(80) NOT NULL default '',

 lastdata varchar(80) NOT NULL default '',

 duration int(11) NOT NULL default '0',

 billsec int(11) NOT NULL default '0',

 start datetime NULL default NULL,

 answer datetime NULL default NULL,

 end datetime NULL default NULL,

 disposition varchar(45) NOT NULL default '',

 amaflags int(11) NOT NULL default '0',

 accountcode varchar(20) NOT NULL default '',

 userfield varchar(255) NOT NULL default '',

 uniqueid varchar(32) NOT NULL default ''

 );

Обратите внимание: в этой таблице (в отличие от таблиц asterisk cdr, представленных в интернете) присутствуют поля: start, answer, end. Эти поля присутствуют в самом CDR, имеют место быть в таблице CDR для Microsoft SQL, но почему-то отсутствуют в большинстве рекомендаций по созданию таблиц CDR для баз MySQL.

Дело в том, что (как указано на сайте voip-info.org), любые стандартные столбцы CDR в базе данных MySQL могут быть исключены простым удалением из таблицы (или переименованием столбца). При этом никаких сообщений об ошибках не возникает – просто соответствующая информация не пишется в базу данных (Standard columns may also be excluded now, simply by dropping the column name from the table, renaming the column, or aliasing the cdrname from a nonexistent variable (e.g. foo => amaflags)).

Поэтому в случае, если в Вашей таблице нет столбцов answer и end (вместо start можно использовать calldate), то рекомендую их туда добавить (иначе время ответа на звонок придется вычислять путем сложения и вычитания нескольких других полей, что далеко не всегда удобно).

Обратите также внимание, что в новых версиях asterisk [не уверен, но предполагаю, что речь идет об asterisk 10-й, 11-й версии и новее] столбец calldate является копией столбца start, в отличие от старых версий asterisk, где столбец calldate является копией столбца end.

Настройка asterisk

Установка компонентов для работы asterisk с MySQL: mysql client и библиотеки mysql для сборки asterisk

Для установки клиента mysql (неважно, установлен ли asterisk на том же компьютере, что и сервер MySQL или нет) запустите в debian следующую команду:

apt-get install mysql-client

В случае, если у Вас установлен RHEL / CentOS, выполните такую команду:

yum install mysql

Теперь необходимо установить библиотеки mysql. Они дадут возможность собирать программы, предназначенные для работы с MySQL.

Для debian это будет команда:

apt-get install libmysqlclient-dev

Для RHEL / CentOS выполните:

yum install mysql-devel

 

Повторная сборка asterisk для работы с MySQL

Перейдите в папку с исходными кодами (откуда устанавливался asterisk) и запустите команду конфирурирования:

cd /usr/src/asterisk-11.4.0/

./configure

make menuselect

В открывшемся меню включите использование следующих компонентов:

  • Add-ons => res_config_mysql
  • Add-ons => cdr_mysql

После выхода (с сохранением) из меню выбора компонентов выполните сборку и повторную установку asterisk:

make

make install

Команду make samples не делать ни в коем случае, это сотрет имеющиеся конфигурационные файлы! Команду make config также выполнять не нужно, поскольку [предполагается, что] asterisk уже установлен и настроен в Вашей системе.

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

Проверка связи с MySQL Server

Давайте проверим работу с сервером MySQL, подключившись к нему с помощью mysql клиента.

Для этого из командной строки запустите:

mysql --host=имя-сервера-MySQL -u имя-пользователя-БД -p

например:

mysql --host=192.168.1.1 -u asterisk_user -p

при этом будет запрошен пароль пользователя asterisk_user, укажите его.

При успешном подключении появится приглашение:

mysql>

теперь можно ввести команды mysql, например:

exit – для выхода

Настройка asterisk для работы с MySQL Server

Для настройки asterisk откройте файл /etc/asterisk/cdr_mysql.conf и впишите туда подобные строки (здесь указан лишь пример):

[global]



hostname=192.168.1.1 ; хост, где находится mysql сервер (может быть localhost или 127.0.0.1

dbname=asteriskcdr ; имя базы данных asterisk

table=cdr ; имя таблицы asterisk

user=asterisk_user ; имя пользователя для базы данных sql

password=ast_password; пароль для пользователя asterisk_user

;timezone=UTC ; часовой пояс (раньше называлась usegmtime)

;charset=UTF-8 ; кодировка базы данных, ее можно узнать в процессе настройки MySQL(необязательный параметр)

Вы можете раскомментировать нужные Вам строки или вписать новые.

После выполнения вышеуказанных действий запустите asterisk и попробуйте подключить модуль cdr_mysql.so. Для этого запустите подключение к asterisk:

asterisk -rvvv

И из командной строки asterisk (asterisk CLI) выполните следующую команду:

module load cdr_mysql.so

При возникновении ошибок решение см. в конце статьи. В случае, если Вы исправили ошибку, и Вам необходимо выгрузить и повторно загрузить модуль, выполните команды:

module unload cdr_mysql.so

module load cdr_mysql.so

В случае успеха asterisk может выдать несколько уведомлений и загрузит модуль. Убедиться в том, что модуль загружен, можно выполнив команду:

module show like cdr_mysql.so

После этого перезагрузите конфигурацию CDR и убедитесь, что звонки фиксируются в базе данных. Для перезагрузки конфигурации CDR выполните команды:

reload cdr

reload cdr_mysql.so

или

reload

На этом настройка asterisk закончена.

 

 

Возможные ошибки, возникающие в процессе настройки MySQL / asterisk

Error 1130 (HY000): Host ‘…’ is not allowed to connect to this MySQL server

Если Вы подключаетесь к серверу MySQL удаленно (с другого компьютера), то может возникать подобное сообщение. Данное сообщение означает, что сервер MySQL не настроен на возможность подключения к нему извне (точнее, что пользователю, под которым Вы пытаетесь подключиться, не разрешено подключение извне). Вам необходимо создать нового пользователя вида user@host, например asterisk_user@192.168.1.1 или asteriskcdr@’%’ (второй вариант дает возможность пользователю asteriskcdr подключаться с любого IP адреса).

Error 1045 (28000): Access denied for user ‘…’ (using password: NO)

При попытке подключения к серверу MySQL с помощью клиента mysql появляется указанное выше сообщение: это (вероятнее всего) означает, что Вы не задали пароль пользователя MySQL при подключении к серверу.

Error 1045 (28000): Access denied for user ‘…’ (using password: YES)

Если при попытке подключения к серверу MySQL с помощью клиента mysql появляется указанное выше сообщение, то это означает, что Вы указали неверный пароль для пользователя MySQL при подключении к серверу.

Error 2003 (HY000): Can’t connect to MySQL server on ‘…’ (113)

Если при попытке подключения к серверу MySQL с помощью клиента mysql (с другого компьютера) появляется указанное выше сообщение, это значит, что у Вас закрыт доступ к порту MySQL данного компьютера. Вероятнее всего, это вызвано неверной настройкой (а точнее, отсутствием настройки на работу с MySQL) службы iptables. Для начала попробуйте просто отключить iptables (остановить службу) и попробуйте подключиться ещё раз.

http://linux.mixed-spb.ru



2017-12-15T09:46:13
Asterisk

Asterisk. Соединение абонента с тем же оператором, при обрыве связи

Задача

Имеется небольшой call-центр. Все входящие звонки с разных линий и номеров сначала поступают на сервер Asterisk (FreeBSD+Asterisk 11.14.1), а он в свою очередь распределяет эти звонки между всеми операторами по определенному сценарию (queues).

При звонке, клиент сначала прослушивает голосовое приветствие, потом его сервер соединяет со свободным оператором, и начинается общение. Но часто бывает, что при плохой связи – звонок обрывает. Клиенту приходится заново перезванивать, слушать опять голосовое приветствие (которое порой может длиться до полуминуты), и попадает на оператора… на другого оператора. Приходится заново  рассказывать о своей проблеме другому оператору и решать все по новой. Порой “качество” связи (мобильной) может упасть на столько, что приходится перезванивать по 5-10 раз !!!

Поэтому было решено сделать так, что бы при обрыве, при повторном звонке, от одного и того же клиента – звонок шел без очереди на того же оператора, без голосовых приветсвий и т.д.

Решение

Решение оказалось довольно простым.

Будем использовать существующую базу Asterisk’а – CDRВ этой базе хранятся все записи и входящих и исходящих звонках нашего телефонного сервера.

Открываем файл /etc/asterisk/extensions.conf и правим нужный нам входящий канал. Добавляем такой блок:

 exten => 100,1,MYSQL(Connect connid IP_MYSQL ЛОГИН_MYSQL ПАРОЛЬ_MYSQL БАЗА_MYSQL)

 exten => 100,n,MYSQL(Query resultid ${connid} select dstchannel from cdr where clid like '%${CDR(src)}' and calldate like '${STRF TIME(${EPOCH},,%Y-%m-%d %H)}%')

 exten => 100,n,MYSQL(Fetch fetchid ${resultid} operator)

 exten => 100,n,GotoIf($["${operator}" = ""]?8:5)

 exten => 100,n,MYSQL(Clear ${resultid})

 exten => 100,n,MYSQL(Disconnect ${connid})

 exten => 100,n,Dial(SIP/${operator:-12:3},20,tT)

 exten => 100,n,Background(hello)

 exten => 100,n,Queue(support)

Что мы делаем

При входящем звонке, соединяемся с базой, делаем запрос, на поиск в таблице cdr в поле clid  по номеру водящего звонка (переменная %${CDR(src)} ) и время укажем последний текущий час (переменная ${STRF TIME(${EPOCH},,%Y-%m-%d %H)}%) в поле calldate.  Если звонок “новый” и еще не звонил в течении часа, то запрос вернет пустое значение в переменную operator, и звонок перекинется на проигрывание приветствия, и звонок поступит в очередь операторов, где на него ответит свободный оператор.

Пример cmd asterisk:

 -- Executing [100@local-phones:1] MYSQL("SIP/INPUT_MTS-0000006c", "Connect connid localhost aster password asterisk") in new stack

 -- Executing [100@local-phones:2] MYSQL("SIP/INPUT_MTS-0000006c", "Query resultid 3 select dstchannel from cdr where clid like '%099xxxxxxx' and calldate like '2017-09-06 09%'") in new stack

 -- Executing [100@local-phones:3] MYSQL("SIP/INPUT_MTS-0000006c", "Fetch fetchid 4 operator") in new stack

 -- Executing [100@local-phones:4] GotoIf("SIP/INPUT_MTS-0000006c", "1?8:5") in new stack

 -- Goto (local-phones,100,8)

 -- Executing [100@local-phones:8] BackGround("SIP/INPUT_MTS-0000006c", "hello") in new stack

 -- <INPUT_MTS-0000006c> Playing 'hello.slin' (language 'ru')

 -- Executing [100@local-phones:9] Queue("SIP/INPUT_MTS-0000006c", "support") in new stack

 -- Started music on hold, class 'default', on SIP/INPUT_MTS-0000006c

 == Using SIP RTP CoS mark 5

 -- SIP/971-0000006d is ringing

 -- SIP/971-0000006d answered SIP/INPUT_MTS-0000006c

 -- Stopped music on hold on SIP/INPUT_MTS-0000006c


Если же, клиент уже звонил и в базе cdr уже существует запись о том, что он звонил. Тогда в переменную operator вернется значение – SIP- номер оператора, с кем он разговаривал, и звонок уже вне очереди поступит напрямую к тому же оператору.

 -- Executing [100@local-phones:1] MYSQL("SIP/INPUT_MTS-0000006a", "Connect connid localhost aster password asterisk") in new stack

 -- Executing [100@local-phones:2] MYSQL("SIP/INPUT_MTS-0000006a", "Query resultid 1 select dstchannel from cdr where clid like '%099xxxxxxx' and calldate like '2017-09-06 09%'") in new stack 

 -- Executing [100@local-phones:3] MYSQL("SIP/INPUT_MTS-0000006a", "Fetch fetchid 2 operator") in new stack

 -- Executing [100@local-phones:4] GotoIf("SIP/INPUT_MTS-0000006a", "0?8:5") in new stack

 -- Goto (local-phones,100,5)

 -- Executing [100@local-phones:5] MYSQL("SIP/INPUT_MTS-0000006a", "Clear 2") in new stack

 -- Executing [100@local-phones:6] MYSQL("SIP/INPUT_MTS-0000006a", "Disconnect 1") in new stack

 -- Executing [100@local-phones:7] Dial("SIP/INPUT_MTS-0000006a", "SIP/971,20,tT") in new stack



2017-09-06T10:41:35
Asterisk