Новости IT, четверг, 18.07.2019
Акимов показал образец российского электронного паспорта
https://u.to/0PDgFQ
Россия вышла на первое место по количеству пользователей браузера Tor
https://u.to/nvHgFQ
Обновление Java SE, MySQL, VirtualBox и других продуктов Oracle с устранением уязвимостей
https://u.to/RPLgFQ
Возобновление работы по интеграции поддержки Tor в Firefox
https://u.to/SfPgFQ
Релиз Proxmox VE 6.0, дистрибутива для организации работы виртуальных серверов
https://u.to/30nfFQ
#news
Акимов показал образец российского электронного паспорта
https://u.to/0PDgFQ
Россия вышла на первое место по количеству пользователей браузера Tor
https://u.to/nvHgFQ
Обновление Java SE, MySQL, VirtualBox и других продуктов Oracle с устранением уязвимостей
https://u.to/RPLgFQ
Возобновление работы по интеграции поддержки Tor в Firefox
https://u.to/SfPgFQ
Релиз Proxmox VE 6.0, дистрибутива для организации работы виртуальных серверов
https://u.to/30nfFQ
#news
И да, кстати, недавно в ансибле выехал патч, который чинит работу с openssl. (были проблемы, например, с установкой соединения с апишкой k8s, в одноименном модуле)
-v=2.8.2
-v=2.8.2
Бесплатный онлайн практикум DevOps by REBRAIN: Docker. Gitlab
Регистрация - http://bit.ly/2YY1fmP
Количество мест строго ограничено!
Практикум по освоению DevOps
Время проведения:
23 Июля (Вторник) в 19:00 по МСК
Что будет на практикуме?
🔹Настраиваем gitlab runners
🔹Собираем Docker образ с помощью Gitlab CI
🔹Деплоим контейнер в production
Кто ведет?
Василий Озеров - основатель агентства Fevlake (fevlake.com) и действующий Devops-инженер (опыт в Devops более 5 лет). Регулярно выступает на RootConf, DevOpsConf Russia, HighLoad.
Открытые еженедельные DevOps практикумы - https://bit.ly/2CGmm3C
Присоединяйтесь!
#реклама
Регистрация - http://bit.ly/2YY1fmP
Количество мест строго ограничено!
Практикум по освоению DevOps
Время проведения:
23 Июля (Вторник) в 19:00 по МСК
Что будет на практикуме?
🔹Настраиваем gitlab runners
🔹Собираем Docker образ с помощью Gitlab CI
🔹Деплоим контейнер в production
Кто ведет?
Василий Озеров - основатель агентства Fevlake (fevlake.com) и действующий Devops-инженер (опыт в Devops более 5 лет). Регулярно выступает на RootConf, DevOpsConf Russia, HighLoad.
Открытые еженедельные DevOps практикумы - https://bit.ly/2CGmm3C
Присоединяйтесь!
#реклама
Telegram
DevOps by REBRAIN
Открытые практикумы по DevOps, Linux, Golang, Networks, HighLoad
Связь с командой: info@rebrainme.com
Сайт: https://rebrainme.com/
Связь с командой: info@rebrainme.com
Сайт: https://rebrainme.com/
Новости IT, понедельник, 22.07.2019
Такого управления в смартфонах мы ещё не видели
https://u.to/95nnFQ
Как настроить общий буфер обмена на Android и Mac
https://u.to/TprnFQ
Взломщики подрядчика ФСБ узнали о тайных проектах спецслужб для слежки в интернете
https://u.to/lJrnFQ
Выпуск модуля LKRG 0.7 для защиты от эксплуатации уязвимостей в ядре Linux
https://u.to/2JrnFQ
Уязвимость в fbdev, эксплуатируемая при подключении вредоносного устройства вывода
https://u.to/G5vnFQ
#news
Такого управления в смартфонах мы ещё не видели
https://u.to/95nnFQ
Как настроить общий буфер обмена на Android и Mac
https://u.to/TprnFQ
Взломщики подрядчика ФСБ узнали о тайных проектах спецслужб для слежки в интернете
https://u.to/lJrnFQ
Выпуск модуля LKRG 0.7 для защиты от эксплуатации уязвимостей в ядре Linux
https://u.to/2JrnFQ
Уязвимость в fbdev, эксплуатируемая при подключении вредоносного устройства вывода
https://u.to/G5vnFQ
#news
1 августа состоится второй Московский митап, посвящённый WebAssembly! В программе blazor, lightbeam и WASI: https://webassembly-moscow.timepad.ru/event/1025337/
P.S. Обязательно нужна предварительная регистрация.
P.S. Обязательно нужна предварительная регистрация.
webassembly-moscow.timepad.ru
WebAssembly Moscow meetup #2 / События на TimePad.ru
Второй московский митап, полностью посвящённый технологии WebAssembly. Огромное спасибо Райффайзенбанк и компании Fluence Labs за помощь в проведении. Будет организована трансляция на youtube и выложены записи докладов.
Новости IT, вторник, 23.07.2019
Вышел сверхмощный смартфон с двумя дисплеями и гигантской батареей, превращаемый в ПК
https://u.to/bUfpFQ
Apple внезапно выпустила iOS 9.3.6 и iOS 10.3.4
https://u.to/uknpFQ
Google увеличила сумму вознаграждения за обнаруженные в браузере Chrome уязвимости
https://u.to/SErpFQ
Роскомнадзор: россияне стали чаще жаловаться на незаконное использование своих персональных данных
https://u.to/RUvpFQ
Выпуск интегрированной среды разработки Apache NetBeans 11.1
https://u.to/8kvpFQ
#news
Вышел сверхмощный смартфон с двумя дисплеями и гигантской батареей, превращаемый в ПК
https://u.to/bUfpFQ
Apple внезапно выпустила iOS 9.3.6 и iOS 10.3.4
https://u.to/uknpFQ
Google увеличила сумму вознаграждения за обнаруженные в браузере Chrome уязвимости
https://u.to/SErpFQ
Роскомнадзор: россияне стали чаще жаловаться на незаконное использование своих персональных данных
https://u.to/RUvpFQ
Выпуск интегрированной среды разработки Apache NetBeans 11.1
https://u.to/8kvpFQ
#news
В честь дня сисадмина скидка 26% на все курсы Слёрма по DevOps/Kubernetes/Ceph/Docker/Ansible.
Только до 28 июля. Промокод BYKVA
Регистрируйтесь по ссылке http://bit.ly/2Yn8VSm
#реклама
Только до 28 июля. Промокод BYKVA
Регистрируйтесь по ссылке http://bit.ly/2Yn8VSm
#реклама
Forwarded from mindsellers
Синтез и распознавание речи с помощью Yandex Speech API, python и asterisk
Сегодня рассмотрим довольно типовую задачу: информирование клиента в автоматическом режиме с синтезом речи, а также распознавание его ответа. Существует некоторое количество бесплатных инструментов как для синтеза, так и для распознавания речи, но к сожалению, ни один из них не может похвастаться высоким качеством работы. Именно поэтому рассмотрим использование платного сервиса от компании Yandex.
В первую очередь потребуется создать аккаунт на Облаке. Привязав любую пластиковую карту(с карты будет списана и тут же возвращена незначительная сумма) мы получим 4000 тестовых рублей аж на два месяца на использование любых облачных сервисов компании. Нас же интересуют исключительно речевые технологии. На момент написания статьи расценки таковы: синтез 1 млн символов - 183 рубля, распознавание фрагмента до 15 секунд - 15.2 копейки, что вполне доступно.
Яндекс предлагает довольно гибкое распределение ролей доступа к системе, но если мы используем только речевые технологии, то нам будет достаточно создать сервисный аккаунт и получить для него API-ключ, который мы будем в дальнейшем использовать в скриптах. Инструкция по данному вопросу доступна по ссылке.
Итак, рассмотрим типовой диалог:
Здравствуйте, Иван Иванович. Ваш заказ номер 234 456 доступен для получения в пункте выдачи по адресу Ленина, 1. Если вы хотите поговорить
с оператором, произнесите слово ОПЕРАТОР
Соединяем с оператором/всего доброго
Начнем со скрипта, который будет генерировать любой текст. На сайте Яндекса есть пример реализации на python, однако в примере рассматривается iam-аутентификация, а мы хотим работать по API-ключу, да и всякие свойства API описаны отдельно. Итак, листинг скрипта ниже, но для того, чтобы он работал, необходимо установить в системе sox, а также поставить requests и pysox через pip
pip install requests
pip install sox
#!/usr/bin/env python
import argparse
import requests
import sox
import os
def synthesize(output, text):
url = 'https://tts.api.cloud.yandex.net/speech/v1/tts:synthesize'
headers = {
'Authorization': 'Api-Key ' + 'AQVN33ioCUgKDF-XDXXXXXXXXX-oWqt7zIrX0ZW-', #авторизация
}
data = {
'text': text, #cинтезируемый текст
'lang': 'ru-RU', #язык
'voice': 'alyss', #голос
'emotion': 'good',
'format': 'lpcm', #формат
'sampleRateHertz': '8000'
}
resp=requests.post(url, headers=headers, data=data, stream=True, verify=False)
if resp.status_code != 200:
raise RuntimeError("Invalid response received: code: %d, message: %s" % (resp.status_code, resp.text))
for chunk in resp.iter_content(chunk_size=None):
with open(output, "wb") as f:
for content in chunk:
f.write(content)
tfm = sox.Transformer()
tfm.set_input_format(file_type='raw', rate=8000, bits=16, channels=1, encoding='signed-integer')
tfm.build(output, output+'.wav')
os.remove(output)
if name == "main":
parser = argparse.ArgumentParser()
parser.add_argument("--text", required=True, help="Text for synthesize")
parser.add_argument("--output", required=True, help="Output file name")
args = parser.parse_args()
synthesize(args.output, args.text)
Итак, мы принимаем 2 аргумента - текст и имя файла. Расширение мы указывать не будем, так как яндекс отдаст нам сырой файл, без заголовков, и далее, с помощью sox, нам все равно придется его превращать в кошерный wav. На выходе мы получим файл с расширением wav, который без проблем "сожрет" asterisk.
Теперь давайте рассмотрим скрипт, который будет заниматься распознаванием текста. В примере Яндекса он написан на python3, что нам, в общем, вполне подходит, так как результат его действий нам все равно нужно получить без перевода каретки(а то asterisk не сможет его обработать), а python2 по умолчанию так не умеет.
#!/usr/bin/env python3
import urllib.request
import json
import sys
import os
file=sys.argv[1]
Сегодня рассмотрим довольно типовую задачу: информирование клиента в автоматическом режиме с синтезом речи, а также распознавание его ответа. Существует некоторое количество бесплатных инструментов как для синтеза, так и для распознавания речи, но к сожалению, ни один из них не может похвастаться высоким качеством работы. Именно поэтому рассмотрим использование платного сервиса от компании Yandex.
В первую очередь потребуется создать аккаунт на Облаке. Привязав любую пластиковую карту(с карты будет списана и тут же возвращена незначительная сумма) мы получим 4000 тестовых рублей аж на два месяца на использование любых облачных сервисов компании. Нас же интересуют исключительно речевые технологии. На момент написания статьи расценки таковы: синтез 1 млн символов - 183 рубля, распознавание фрагмента до 15 секунд - 15.2 копейки, что вполне доступно.
Яндекс предлагает довольно гибкое распределение ролей доступа к системе, но если мы используем только речевые технологии, то нам будет достаточно создать сервисный аккаунт и получить для него API-ключ, который мы будем в дальнейшем использовать в скриптах. Инструкция по данному вопросу доступна по ссылке.
Итак, рассмотрим типовой диалог:
Здравствуйте, Иван Иванович. Ваш заказ номер 234 456 доступен для получения в пункте выдачи по адресу Ленина, 1. Если вы хотите поговорить
с оператором, произнесите слово ОПЕРАТОР
Соединяем с оператором/всего доброго
Начнем со скрипта, который будет генерировать любой текст. На сайте Яндекса есть пример реализации на python, однако в примере рассматривается iam-аутентификация, а мы хотим работать по API-ключу, да и всякие свойства API описаны отдельно. Итак, листинг скрипта ниже, но для того, чтобы он работал, необходимо установить в системе sox, а также поставить requests и pysox через pip
pip install requests
pip install sox
#!/usr/bin/env python
import argparse
import requests
import sox
import os
def synthesize(output, text):
url = 'https://tts.api.cloud.yandex.net/speech/v1/tts:synthesize'
headers = {
'Authorization': 'Api-Key ' + 'AQVN33ioCUgKDF-XDXXXXXXXXX-oWqt7zIrX0ZW-', #авторизация
}
data = {
'text': text, #cинтезируемый текст
'lang': 'ru-RU', #язык
'voice': 'alyss', #голос
'emotion': 'good',
'format': 'lpcm', #формат
'sampleRateHertz': '8000'
}
resp=requests.post(url, headers=headers, data=data, stream=True, verify=False)
if resp.status_code != 200:
raise RuntimeError("Invalid response received: code: %d, message: %s" % (resp.status_code, resp.text))
for chunk in resp.iter_content(chunk_size=None):
with open(output, "wb") as f:
for content in chunk:
f.write(content)
tfm = sox.Transformer()
tfm.set_input_format(file_type='raw', rate=8000, bits=16, channels=1, encoding='signed-integer')
tfm.build(output, output+'.wav')
os.remove(output)
if name == "main":
parser = argparse.ArgumentParser()
parser.add_argument("--text", required=True, help="Text for synthesize")
parser.add_argument("--output", required=True, help="Output file name")
args = parser.parse_args()
synthesize(args.output, args.text)
Итак, мы принимаем 2 аргумента - текст и имя файла. Расширение мы указывать не будем, так как яндекс отдаст нам сырой файл, без заголовков, и далее, с помощью sox, нам все равно придется его превращать в кошерный wav. На выходе мы получим файл с расширением wav, который без проблем "сожрет" asterisk.
Теперь давайте рассмотрим скрипт, который будет заниматься распознаванием текста. В примере Яндекса он написан на python3, что нам, в общем, вполне подходит, так как результат его действий нам все равно нужно получить без перевода каретки(а то asterisk не сможет его обработать), а python2 по умолчанию так не умеет.
#!/usr/bin/env python3
import urllib.request
import json
import sys
import os
file=sys.argv[1]
Forwarded from mindsellers
FOLDER_ID = "default" # Идентификатор каталога
API = "AQVN33ioCUgKDF-XXXXXXXXX-oWqt7zIrX0ZW-"
with open(file, "rb") as f:
data = f.read()
params = "&".join([
"topic=general",
"format=lpcm",
"sampleRateHertz=8000",
"lang=ru-RU"
])
url = urllib.request.Request("https://stt.api.cloud.yandex.net/speech/v1/stt:recognize?%s" % params, data=data)
url.add_header("Authorization", "Api-Key %s" % API)
responseData = urllib.request.urlopen(url).read().decode('UTF-8')
decodedData = json.loads(responseData)
os.remove(file)
if decodedData.get("error_code") is None:
resp=decodedData.get("result")
if resp.startswith('да') or resp.startswith('хорошо') or resp.startswith('норм') or resp.startswith('ладно') or 'оператор' in resp:
print('yes',end='')
elif resp.startswith('нет'):
print('no',end='')
elif 'абонент' in resp:
print('no',end='')
elif 'авто' in resp:
print('no',end='')
elif resp=='':
print('no',end='')
else:
print('dont',end='')
Здесь, в принципе, все понятно без комментариев - мы по-прежнему указываем в данных, что именно мы передаем, подсовываем файл с записью и получаем результат. В зависимости от того, что было распознано, мы получаем от скрипта в stdout yes, no или dont, соответственно, Да, Нет и Не понял.
В рассматриваемом примере, к сожалению, никакой интеграции asterisk с crm-системой нет, так что пойдем по пути наименьшего сопротивления, и будем принимать данные через get-запрос. Сделать это можно по-разному: от написания собственного мультипоточного socket-сервера до использования django, но я решил использовать супер-легковесный web-фреймворк под названием bottle. Так что начинаем с
pip install bottle
Сам фреймворк целиком состоит из единственного файла, так что можно его просто скачать и положить в каталог со своим приложением. Итак, перейдем к коду:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from bottle import run, request, get
import os
from syn import synthesize
def autodial(mobile,order):
with open('/tmp/'+str(mobile)+str(order), 'w') as callfile:
callfile.write('Channel: Local/'+mobile+'@from-internal'+'\n')
callfile.write('Callerid: Autodial <'+mobile+'>\n')
callfile.write('Context: from-internal\n')
callfile.write('Extension: 900\n')
callfile.write('Priority: 1\n')
callfile.write('WaitTime: 25000\n')
callfile.write('Set: __ORDER='+str(order)+'\n')
os.rename('/tmp/'+str(mobile)+str(order), '/var/spool/asterisk/outgoing/'+str(mobile)+str(order))
@get('/msg')
def index():
postdata = request.body.read()
name = request.query.get("name")
surname = request.query.get("surname")
number = request.query.get("number")
order = request.query.get("order")
address = request.query.get("address")
synthesize(output='/tmp/'+str(order)+'-name',text=str(name)+' '+str(surname))
synthesize(output='/tmp/'+str(order)+'-order',text=str(order))
synthesize(output='/tmp/'+str(order)+'-address',text=str(address))
autodial(mobile=number,order=order)
run(host='192.168.0.22', port=8000, debug=False)
Итак, после запуска сервера на указанном адресе и порту, мы отслеживаем исключительно get-запросы в /msg. Функция autodial в данном случае формирует callfile для asterisk, причем только после того, как мы сформировали необходимые файлы. Функция synthesize импортируется из первого скрипта. Запустим скрипт и в браузере откроем ссылку
http://192.168.0.22:8000/msg?name=Иван&surname=Петров&order=23232&address=Ленина 1&number=89278555666
Результатом работы данного кода будет:
три файла с названиями вида /tmp/23232-name.wav /tmp/23232-order.wav /tmp/23232-address.wav
callfile, который осуществит вызов клиента, соединит его со служебным номером 900, а также передаст в контекст переменную ORDER, соответствующую номеру заказа.
Теперь нам нужно сгенерировать те части фразы, которые будут неизменны. Сделаем это с помощью нашего скрипта, например,
API = "AQVN33ioCUgKDF-XXXXXXXXX-oWqt7zIrX0ZW-"
with open(file, "rb") as f:
data = f.read()
params = "&".join([
"topic=general",
"format=lpcm",
"sampleRateHertz=8000",
"lang=ru-RU"
])
url = urllib.request.Request("https://stt.api.cloud.yandex.net/speech/v1/stt:recognize?%s" % params, data=data)
url.add_header("Authorization", "Api-Key %s" % API)
responseData = urllib.request.urlopen(url).read().decode('UTF-8')
decodedData = json.loads(responseData)
os.remove(file)
if decodedData.get("error_code") is None:
resp=decodedData.get("result")
if resp.startswith('да') or resp.startswith('хорошо') or resp.startswith('норм') or resp.startswith('ладно') or 'оператор' in resp:
print('yes',end='')
elif resp.startswith('нет'):
print('no',end='')
elif 'абонент' in resp:
print('no',end='')
elif 'авто' in resp:
print('no',end='')
elif resp=='':
print('no',end='')
else:
print('dont',end='')
Здесь, в принципе, все понятно без комментариев - мы по-прежнему указываем в данных, что именно мы передаем, подсовываем файл с записью и получаем результат. В зависимости от того, что было распознано, мы получаем от скрипта в stdout yes, no или dont, соответственно, Да, Нет и Не понял.
В рассматриваемом примере, к сожалению, никакой интеграции asterisk с crm-системой нет, так что пойдем по пути наименьшего сопротивления, и будем принимать данные через get-запрос. Сделать это можно по-разному: от написания собственного мультипоточного socket-сервера до использования django, но я решил использовать супер-легковесный web-фреймворк под названием bottle. Так что начинаем с
pip install bottle
Сам фреймворк целиком состоит из единственного файла, так что можно его просто скачать и положить в каталог со своим приложением. Итак, перейдем к коду:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from bottle import run, request, get
import os
from syn import synthesize
def autodial(mobile,order):
with open('/tmp/'+str(mobile)+str(order), 'w') as callfile:
callfile.write('Channel: Local/'+mobile+'@from-internal'+'\n')
callfile.write('Callerid: Autodial <'+mobile+'>\n')
callfile.write('Context: from-internal\n')
callfile.write('Extension: 900\n')
callfile.write('Priority: 1\n')
callfile.write('WaitTime: 25000\n')
callfile.write('Set: __ORDER='+str(order)+'\n')
os.rename('/tmp/'+str(mobile)+str(order), '/var/spool/asterisk/outgoing/'+str(mobile)+str(order))
@get('/msg')
def index():
postdata = request.body.read()
name = request.query.get("name")
surname = request.query.get("surname")
number = request.query.get("number")
order = request.query.get("order")
address = request.query.get("address")
synthesize(output='/tmp/'+str(order)+'-name',text=str(name)+' '+str(surname))
synthesize(output='/tmp/'+str(order)+'-order',text=str(order))
synthesize(output='/tmp/'+str(order)+'-address',text=str(address))
autodial(mobile=number,order=order)
run(host='192.168.0.22', port=8000, debug=False)
Итак, после запуска сервера на указанном адресе и порту, мы отслеживаем исключительно get-запросы в /msg. Функция autodial в данном случае формирует callfile для asterisk, причем только после того, как мы сформировали необходимые файлы. Функция synthesize импортируется из первого скрипта. Запустим скрипт и в браузере откроем ссылку
http://192.168.0.22:8000/msg?name=Иван&surname=Петров&order=23232&address=Ленина 1&number=89278555666
Результатом работы данного кода будет:
три файла с названиями вида /tmp/23232-name.wav /tmp/23232-order.wav /tmp/23232-address.wav
callfile, который осуществит вызов клиента, соединит его со служебным номером 900, а также передаст в контекст переменную ORDER, соответствующую номеру заказа.
Теперь нам нужно сгенерировать те части фразы, которые будут неизменны. Сделаем это с помощью нашего скрипта, например,
Forwarded from mindsellers
./syn.py --output='/opt/autodial/syn/сonnect' --text='Ваш звонок переводится на оператора '
Повторим эту процедуру для всех необходимых фраз, и получим файлы
address.wav
goodbye.wav
hello.wav
operator.wav
order.wav
сonnect.wav
размещенные в указанном каталоге.
Самое время заняться asterisk. По старой традиции я покажу пример с FreePBX, так как на чистом asterisk все во-первых, чуть проще, а во-вторых, работают более опытные люди, которым мои контексты, в общем-то, и не нужны.
В секцию [from-internal-custom] файла extensions_custom.conf внесем следующее:
exten => 900,1,Answer()
exten => 900,n,Noop(${ORDER})
exten => 900,n,Playback(/opt/autodial/syn/hello) ;здравствуйте
exten => 900,n,Playback(/tmp/${ORDER}-name) ;Иван Петров
exten => 900,n,Playback(/opt/autodial/syn/order) ;ваш заказ с номером
exten => 900,n,Playback(/tmp/${ORDER}-order) ;23232
exten => 900,n,Playback(/opt/autodial/syn/address) ;готов к выдаче по адресу
exten => 900,n,Playback(/tmp/${ORDER}-address) ;Ленина 1
exten => 900,n,Playback(/opt/autodial/syn/operator) ;Если вы хотите соединиться
;с оператором, скажите ОПЕРАТОР
exten => 900,n(record),Monitor(wav,/tmp/${UNIQUEID},o) ;включаем запись
exten => 900,n,Wait(2) ;ждем 2 секунды
exten => 900,n,StopMonitor() ;останавливаем
exten => 900,n,Noop(/tmp/${UNIQUEID}-in.wav)
exten => 900,n,Set(RESULT=${SHELL(/usr/bin/python3 /opt/autodial/yandex.py /tmp/${UNIQUEID}-in.wav)})
;передаем запись скрипту и ждем результата
exten => 900,n,Noop(${RESULT})
exten => 900,n,GotoIf($["${RESULT}" = "yes"]?yes) ;если он yes, переходим на метку
exten => 900,n,Playback(/opt/autodial/syn/goodbye) ;иначе прощаемся
exten => 900,n,Hangup()
exten => 900,n(yes),Playback(/opt/autodial/syn/сonnect) ;Ваш звонок переводится на оператора
exten => 900,n,Goto(from-internal,600,1) ;Соединение с оператором или очередью
exten => 900,n,Hangup()
Как несложно заметить, в данном случае мы обрабатывали только один ответ скрипта, положительный. Однако сам скрипт отдает, как было сказано выше, 3 разных варианта(как обычно, скрипт остался от другой задачи)
На этом, собственно, все. Из возможных доработок видится логичным записать заранее все адреса пунктов выдачи, и не генерировать их, а в переменной address в get-запросе передавать просто порядковый номер пункта. Записи в таком случае имеет смысл назвать address-1, address-2 и так далее, при формировании callfile передать также переменную ADDRESS, ну и соответственно, проигрывать файл с именем address-${ADDRESS} из контекста.
Листинг скриптов удобнее посмотреть в wiki
http://pubwiki.mindsellers.ru/index.php/%D0%A1%D0%B8%D0%BD%D1%82%D0%B5%D0%B7_%D0%B8_%D1%80%D0%B0%D1%81%D0%BF%D0%BE%D0%B7%D0%BD%D0%B0%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D1%80%D0%B5%D1%87%D0%B8_%D1%81_%D0%BF%D0%BE%D0%BC%D0%BE%D1%89%D1%8C%D1%8E_Yandex_Speech_API
#python #asterisk #yandex #speech
Повторим эту процедуру для всех необходимых фраз, и получим файлы
address.wav
goodbye.wav
hello.wav
operator.wav
order.wav
сonnect.wav
размещенные в указанном каталоге.
Самое время заняться asterisk. По старой традиции я покажу пример с FreePBX, так как на чистом asterisk все во-первых, чуть проще, а во-вторых, работают более опытные люди, которым мои контексты, в общем-то, и не нужны.
В секцию [from-internal-custom] файла extensions_custom.conf внесем следующее:
exten => 900,1,Answer()
exten => 900,n,Noop(${ORDER})
exten => 900,n,Playback(/opt/autodial/syn/hello) ;здравствуйте
exten => 900,n,Playback(/tmp/${ORDER}-name) ;Иван Петров
exten => 900,n,Playback(/opt/autodial/syn/order) ;ваш заказ с номером
exten => 900,n,Playback(/tmp/${ORDER}-order) ;23232
exten => 900,n,Playback(/opt/autodial/syn/address) ;готов к выдаче по адресу
exten => 900,n,Playback(/tmp/${ORDER}-address) ;Ленина 1
exten => 900,n,Playback(/opt/autodial/syn/operator) ;Если вы хотите соединиться
;с оператором, скажите ОПЕРАТОР
exten => 900,n(record),Monitor(wav,/tmp/${UNIQUEID},o) ;включаем запись
exten => 900,n,Wait(2) ;ждем 2 секунды
exten => 900,n,StopMonitor() ;останавливаем
exten => 900,n,Noop(/tmp/${UNIQUEID}-in.wav)
exten => 900,n,Set(RESULT=${SHELL(/usr/bin/python3 /opt/autodial/yandex.py /tmp/${UNIQUEID}-in.wav)})
;передаем запись скрипту и ждем результата
exten => 900,n,Noop(${RESULT})
exten => 900,n,GotoIf($["${RESULT}" = "yes"]?yes) ;если он yes, переходим на метку
exten => 900,n,Playback(/opt/autodial/syn/goodbye) ;иначе прощаемся
exten => 900,n,Hangup()
exten => 900,n(yes),Playback(/opt/autodial/syn/сonnect) ;Ваш звонок переводится на оператора
exten => 900,n,Goto(from-internal,600,1) ;Соединение с оператором или очередью
exten => 900,n,Hangup()
Как несложно заметить, в данном случае мы обрабатывали только один ответ скрипта, положительный. Однако сам скрипт отдает, как было сказано выше, 3 разных варианта(как обычно, скрипт остался от другой задачи)
На этом, собственно, все. Из возможных доработок видится логичным записать заранее все адреса пунктов выдачи, и не генерировать их, а в переменной address в get-запросе передавать просто порядковый номер пункта. Записи в таком случае имеет смысл назвать address-1, address-2 и так далее, при формировании callfile передать также переменную ADDRESS, ну и соответственно, проигрывать файл с именем address-${ADDRESS} из контекста.
Листинг скриптов удобнее посмотреть в wiki
http://pubwiki.mindsellers.ru/index.php/%D0%A1%D0%B8%D0%BD%D1%82%D0%B5%D0%B7_%D0%B8_%D1%80%D0%B0%D1%81%D0%BF%D0%BE%D0%B7%D0%BD%D0%B0%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D1%80%D0%B5%D1%87%D0%B8_%D1%81_%D0%BF%D0%BE%D0%BC%D0%BE%D1%89%D1%8C%D1%8E_Yandex_Speech_API
#python #asterisk #yandex #speech
Новости IT, среда, 24.07.2019
В России могут запретить пользоваться новыми iPhone на работе
https://u.to/9SjrFQ
Смотрим на красивый концепт Android 11 R
https://u.to/CyrrFQ
Госдума нашла противоречие Конституции в законопроекте об идентификации пользователей сервисов электронной почты
https://u.to/gCzrFQ
Google заблокирует сертификаты DarkMatter в Chrome и Android
https://u.to/IS3rFQ
Уязвимость, позволяющая дополнениям Chrome выполнять внешний код, несмотря на права доступа
https://u.to/dC3rFQ
#news
В России могут запретить пользоваться новыми iPhone на работе
https://u.to/9SjrFQ
Смотрим на красивый концепт Android 11 R
https://u.to/CyrrFQ
Госдума нашла противоречие Конституции в законопроекте об идентификации пользователей сервисов электронной почты
https://u.to/gCzrFQ
Google заблокирует сертификаты DarkMatter в Chrome и Android
https://u.to/IS3rFQ
Уязвимость, позволяющая дополнениям Chrome выполнять внешний код, несмотря на права доступа
https://u.to/dC3rFQ
#news
Я.Облако, заметка
Очень интересный момент сегодня выяснил. https://cloud.yandex.ru/support - это на самом деле не технический сапорт, а вопросы связанные с отделом продаж. Поэтому если у вас будут технические вопросы, ищите форму связи с поддержкой в специальном разделе консоли, которая доступна после подключения к яндекс.облаку.
Очень интересный момент сегодня выяснил. https://cloud.yandex.ru/support - это на самом деле не технический сапорт, а вопросы связанные с отделом продаж. Поэтому если у вас будут технические вопросы, ищите форму связи с поддержкой в специальном разделе консоли, которая доступна после подключения к яндекс.облаку.
Бесплатный онлайн практикум DevOps by REBRAIN: Ansible
Регистрация - http://bit.ly/2MeA7ft
Количество мест строго ограничено!
Практикум по освоению DevOps
Время проведения:
30 Июля (Вторник) в 19:00 по МСК
Что будет на практикуме?
🔹Зачем нужны системы управления конфигурациями?
🔹Обзор систем управления конфигурациями
🔹Основы работы с ansible - настраиваем первый сервер
🔹Деплоим докер с помощью ансибла
Кто ведет?
Василий Озеров - основатель агентства Fevlake (fevlake.com) и действующий Devops-инженер (опыт в Devops более 5 лет). Регулярно выступает на RootConf, DevOpsConf Russia, HighLoad.
Открытые еженедельные DevOps практикумы - http://bit.ly/2J5Jts2
Присоединяйтесь!
#реклама
Регистрация - http://bit.ly/2MeA7ft
Количество мест строго ограничено!
Практикум по освоению DevOps
Время проведения:
30 Июля (Вторник) в 19:00 по МСК
Что будет на практикуме?
🔹Зачем нужны системы управления конфигурациями?
🔹Обзор систем управления конфигурациями
🔹Основы работы с ansible - настраиваем первый сервер
🔹Деплоим докер с помощью ансибла
Кто ведет?
Василий Озеров - основатель агентства Fevlake (fevlake.com) и действующий Devops-инженер (опыт в Devops более 5 лет). Регулярно выступает на RootConf, DevOpsConf Russia, HighLoad.
Открытые еженедельные DevOps практикумы - http://bit.ly/2J5Jts2
Присоединяйтесь!
#реклама
Новости IT, понедельник, 29.07.2019
Программист внедрил логическую бомбу в таблицы Excel, чтобы гарантировать себе заказы на техподдержку
https://u.to/BHz0FQ
Отжим бизнеса по-русски. Акции «Яндекса» рухнули после внесения законопроекта о национализации «значимых IT-ресурсов»
https://u.to/73z0FQ
Выпуск Latte Dock 0.9, альтернативной панели для KDE
https://u.to/X4H0FQ
GitHub начал ограничивать пользователей с территорий, подпадающих под санкции США
https://u.to/RYL0FQ
Вышло обновление мобильной ОС Sailfish 3.1: улучшенный дизайн, безопасность и удобство работы
https://u.to/E4X0FQ
#news
Программист внедрил логическую бомбу в таблицы Excel, чтобы гарантировать себе заказы на техподдержку
https://u.to/BHz0FQ
Отжим бизнеса по-русски. Акции «Яндекса» рухнули после внесения законопроекта о национализации «значимых IT-ресурсов»
https://u.to/73z0FQ
Выпуск Latte Dock 0.9, альтернативной панели для KDE
https://u.to/X4H0FQ
GitHub начал ограничивать пользователей с территорий, подпадающих под санкции США
https://u.to/RYL0FQ
Вышло обновление мобильной ОС Sailfish 3.1: улучшенный дизайн, безопасность и удобство работы
https://u.to/E4X0FQ
#news
Новости IT, среда, 31.07.2019
Рассекречен смартфон на Debian Linux с защитой от «большого брата».
https://u.to/Gd32FQ
Что не так с Android Q. Кто-то удивлен?
https://u.to/XN72FQ
Представлен первый предварительный выпуск Fedora CoreOS
https://u.to/eN-2FQ
11 удалённо эксплуатируемых уязвимостей в TCP/IP стеке VxWorks
https://u.to/FuD2FQ
Китайцы скупают крипту в Москве, и это не биткоины
https://u.to/7OH2FQ
#news
Рассекречен смартфон на Debian Linux с защитой от «большого брата».
https://u.to/Gd32FQ
Что не так с Android Q. Кто-то удивлен?
https://u.to/XN72FQ
Представлен первый предварительный выпуск Fedora CoreOS
https://u.to/eN-2FQ
11 удалённо эксплуатируемых уязвимостей в TCP/IP стеке VxWorks
https://u.to/FuD2FQ
Китайцы скупают крипту в Москве, и это не биткоины
https://u.to/7OH2FQ
#news
Задачи на собеседование
Недавно мне попалась на глаза задача на вакансию linux-администратора в одну известную компанию. Вопрос звучит следующим образом:
Вам нужно проапгрейдить ядро и операционную систему на ста одинаково настроенных серверах. Как вы будете решать эту задачу?
Вопрос никоим образом не сложный, но позволяет сразу прочувствовать знания соискателя. Прежде чем высказать свое ИМХО по этому вопросу, я запущу опрос и дам вам время чтобы вы могли составить собственное мнение.
Недавно мне попалась на глаза задача на вакансию linux-администратора в одну известную компанию. Вопрос звучит следующим образом:
Вам нужно проапгрейдить ядро и операционную систему на ста одинаково настроенных серверах. Как вы будете решать эту задачу?
Вопрос никоим образом не сложный, но позволяет сразу прочувствовать знания соискателя. Прежде чем высказать свое ИМХО по этому вопросу, я запущу опрос и дам вам время чтобы вы могли составить собственное мнение.
Вам нужно проапгрейдить ядро и операционную систему на ста одинаково настроенных серверах. Как вы будете решать эту задачу?
Anonymous Poll
17%
Посмотреть результаты
2%
Буду запускать на серверах по-очереди что-то вроде apt dist-upgrade
8%
Воспользуюсь какой-нибудь системой наподобие ansible и запущу в ней apt dist-upgrade
27%
Обновлю руками один сервер, а потом запущу ansible
46%
Вопрос на самом деле гораздо более глубокий и требует изучения софта, который установлен на сервере.