Я начал свою карьеру в области разработки программного обеспечения, написав приложения для колл-центра в небольшом банке во Флориде. Я помню, что банк приобрел любой «Cadillac» систем интерактивного голосового ответа (IVR) за те сумасшедшие деньги. Сегодня вы можете создать IVR за ночь, используя Twilio .
Когда вы регистрируетесь в Twilio, вы можете выбрать свой номер телефона (более или менее). Например, я выбрал +1 (636) 451-7411, что означает +1 ( нео ) 4j 1-7 411 . Если вы позвоните по этому номеру прямо сейчас (при условии, что у меня не закончились кредиты Twilio), вы подключитесь к моему IVR.
Несколько лет назад я построил один для фирмы по управлению имуществом, я буду использовать это в качестве примера.
response = Twilio::TwiML::Response.new do |r| r.Say "Thank you for calling the Neo4j I V R demo.", :voice => "alice" r.Gather :action => "/mainmenu", :numDigits => 1 do r.Say "For quality assurance purposes this call may be recorded", :voice => "alice" r.Say "For rent payment options and billing questions, press 1", :voice => "alice" r.Say "To submit a maintenance request, press 2", :voice => "alice" r.Say "For all other tenant related questions press 3", :voice => "alice" r.Say "To repeat this message press 9", :voice => "alice" end r.Say "Sorry, I didn\"t get your response.", :voice => "alice" r.Play "http://neo-ivr.herokuapp.com/" + "hello.mp3" r.Redirect "/", :method => "GET" end
Приведенный выше код генерирует XML-файл, который интерпретирует Twilio. Если вы нажмете «2» для отправки запроса на обслуживание, вы получите другое меню, сгенерированное этим кодом:
post "/maintenance" do add_event(request, "/maintenance") response = Twilio::TwiML::Response.new do |r| r.Gather :action => "/maintenance-input", :numDigits => 1 do r.Say "if your heat is out, press 1 ", :voice => "alice" r.Say "if there is a problem with your plumbing, press 2", :voice => "alice" r.Say "for all other maintenance questions, press 3", :voice => "alice" r.Say "to return to the previous menu, press 0", :voice => "alice" r.Say "to repeat this message press 9", :voice => "alice" end r.Say "Sorry, I didn\"t get your response.", :voice => "alice" r.Play "http://neo-ivr.herokuapp.com/" + "hello.mp3" r.Redirect "/maintenance" end response.text end
Пользователи IVR будут перемещаться по этому меню и сообщать о проблемах, которые у них есть, или отчаянно начинать нажимать кнопки, пока не получат возможность общаться с человеком. Чем дольше они добираются туда, куда им нужно, тем злее они становятся. Если бы только был способ отследить пути через систему … о да … Neo4j .
Проницательный наблюдатель, возможно, заметил вызов метода «add_event» в приведенном выше коде, давайте посмотрим, что он делает:
def add_event(request, url) $neo.commit_transaction(["MATCH (old:Event {session: {session}})<-[:PREV*0..]-(latest) WHERE NOT(latest<-[:PREV]-()) WITH latest LIMIT 1 CREATE (latest)<-[:PREV]-(e:Event {session: {session}, url: {url}}) WITH e MATCH (u:User {number: {number}}), (p:Page {url: {url}}) CREATE (u)-[:DIALED]->(e)-[:ON]->(p) RETURN e", {:number => request["From"], :url => url, :session => request["CallSid"]} ]) end
Neo4j сообщает, что произошло новое событие и что оно должно добавить его в цепочку событий этого пользователя и сеанса. Мы ищем последнее событие этого сеанса и создаем новое «предыдущее» отношение с новым событием, которое указывает на пользователя и страницу, на которой оно произошло. По мере того, как пользователи звонят, наш график становится все более интересным, и довольно скоро вы можете начать визуализировать вызовы, чтобы понять их.
Мы будем использовать библиотеку JavaScript D3 и заимствовать плагин Sankey для нашей визуализации.
Запрос Cypher, который генерирует эту визуализацию, начинается с корня и проходит на расстоянии до 3 прыжков, подсчитывает пути и возвращает их нам. Небольшая рубиновая магия превращает этот шифр в JSON, который D3.js может понять, и это все, что нужно сделать.
MATCH path=(p:Page {url:'/'})<-[:ON]-()-[:PREV*0..3]-() RETURN EXTRACT(v in NODES(path)[1..LENGTH(path)+1] | v.url), count(path) ORDER BY count(path) DESC LIMIT 20
На изображении выше мы видим, что большинство людей звонят, чтобы сделать платеж, и немногие звонят, чтобы жаловаться на сантехнику. Это одна из тех вещей, которые не могут ждать до следующей недели, и большинство людей позаботятся об этом самостоятельно.
Мы развернем на Heroku
используя плагин GrapheneDB .
Я создал приложение Twilio, которое указывает на heroku:
… и установить мой номер, чтобы указать на приложение:
Теперь у меня нет персонала, чтобы ответить на ваш звонок, и он точно не будет перенаправлен на мой мобильный телефон, поэтому вместо этого я решил, что конец дерева меню IVR будет воспроизводить небольшие звуковые фрагменты определенного «Отменили слишком рано научно-фантастический сериал» плюс пасхальное яйцо или две брошенные туда. Проблемы с жарой? Может быть, вы должны позвонить в: +1 ( нео ) 4j 1-7 411 .
Полный исходный код доступен на github как обычно. Я действительно хотел бы поблагодарить Ника Дингуолла, который сделал большую серию на эту тему для веб-трафика в своем блоге .