Commit a80ef648 by Anna Sokolova

first commit

0 parents
node_modules/
audio/
logs/
threads/
package-lock.json
log.txt
MIT License
Copyright (c) 2020 Dasha Samples
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
# How to start the application
Megafon inline support on Dasha.AI platform Prerecord Development version
1. Clone the repo and install the dependencies:
```sh
git clone git@gitlab.veeble.ru:Anna/avito-test-dev.git
cd avito-test-dev
touch log.txt
mkdir -p stt audio
chmod a+rw log.txt logs threads audio app/phrasemap.json
npm install
```
2. To start a text chat, run:
```sh
npm start chat
```
3. To receive a phone call from Dasha, run:
```sh
npm start <your phone number>
```
The phone number should be in the international format without the `+` (e.g. `12223334455`)
{
"formatVersion": "2",
"dialogue": {
"file": "main.dsl"
},
"nlu": {
"language": "ru-RU",
"skills": [
"sentiment",
"common_phrases",
"common-numbers"
],
"customIntents": {
"file": "intents.json"
}
},
"nlg": {
"type": "phrases",
"file": "phrasemap.json",
"signatureFile": "phrasemap.json"
},
"name": "avito-test-dev"
}
library
import "canHearYou.dsl";
import "dontUnderstand.dsl";
import "hangup.dsl";
import "hello.dsl";
import "repeatAndPing.dsl";
library
digression call_operator
{
conditions { on #messageHasAnyIntent(digression.call_operator.triggers); }
var retriesLimit = 2;
var counter = 0;
var resetOnRecognized=false;
var triggers = ["call_operator"];
var responses: Phrases[] = ["call_operator"];
do
{
$cjm.push("call_operator");
for (var item in digression.call_operator.responses)
{
#say(item, repeatMode: "ignore");
}
#repeat(accuracy: "repeat");
return;
}
transitions
{
}
}
\ No newline at end of file
library
digression can_hear_you
{
conditions { on #messageHasAnyIntent(digression.can_hear_you.triggers) priority -100; }
var triggers = ["can_you_hear_me"];
var responses: Phrases[] = ["i_can_hear_you"];
do
{
for (var item in digression.can_hear_you.responses)
{
#say(item, repeatMode: "ignore");
}
return;
}
transitions
{
}
}
library
context
{
output status:string?;
output serviceStatus:string?;
}
digression dont_understand_hangup_params
{
conditions { on false; }
var responses: Phrases[] = ["dont_understand_forward"];
var status = "DontUnderstandHangup";
var serviceStatus = "Done";
do
{
}
transitions
{
}
}
digression dont_understand
{
conditions { on true priority -1000; }
var retriesLimit=2;
var counter=0;
var resetOnRecognized=false;
var responses: Phrases[] = ["dont_understand"];
do
{
if (digression.dont_understand.counter == 2)
{
goto hangup;
}
set digression.dont_understand.counter=digression.dont_understand.counter+1;
set digression.dont_understand.resetOnRecognized = false;
for (var item in digression.dont_understand.responses)
{
#say(item, repeatMode: "ignore");
//#say("dont_understand_question");
}
#repeat(accuracy: "short");
return;
}
transitions
{
hangup: goto dont_understand_hangup;
}
}
preprocessor digression dont_understand_preprocessor
{
conditions { on true priority 50000; }
do
{
if (digression.dont_understand.resetOnRecognized)
{
set digression.dont_understand.counter = 0;
}
set digression.dont_understand.resetOnRecognized = true;
return;
}
transitions
{
}
}
node dont_understand_hangup
{
do
{
$cjm.push("dont_understand_hangup");
for (var item in digression.dont_understand_hangup_params.responses)
{
#say(item, repeatMode: "ignore");
}
set $status=digression.dont_understand_hangup_params.status;
set $serviceStatus=digression.dont_understand_hangup_params.serviceStatus;
//#forward("12223334455"); //use if you want to transfer a call
//#disconnect();
goto do_before_exit;
}
transitions
{
do_before_exit: goto do_before_exit;
}
}
library
context
{
output serviceStatus: string?;
}
digression hangup
{
conditions
{
on true tags: onclosed;
}
var serviceStatus = "UserHangup";
do
{
$cjm.push("hangup");
set $serviceStatus = digression.hangup.serviceStatus;
//#disconnect();
goto do_before_exit;
}
transitions
{
do_before_exit: goto do_before_exit;
}
}
library
/**
* Reaction if nothing meaningful happens in the dialogue for too long.
*/
preprocessor digression hello
{
conditions { on #getIdleTime() - digression.hello.lastIdleTime > digression.hello.idleTimeLimit tags: ontick; }
var idleTimeLimit=8000;
var lastIdleTime=0;
var retriesLimit=2;
var counter=0;
do
{
set digression.hello.lastIdleTime=#getIdleTime();
if (digression.hello.counter > digression.hello.retriesLimit)
{
goto hangup;
}
set digression.hello.counter=digression.hello.counter+1;
#say("hello", repeatMode: "ignore");
// #say("dont_understand_question");
#repeat(accuracy: "short");
return;
}
transitions
{
hangup: goto hello_hangup;
}
}
preprocessor digression hello_preprocessor
{
conditions { on true priority 50000; }
do
{
set digression.hello.lastIdleTime = 0;
set digression.hello.counter = 0;
return;
}
transitions
{
}
}
node hello_hangup
{
do
{
$cjm.push("hello_hangup");
#say("dont_understand_hangup");
set $status="EmptyCall";
set $serviceStatus="Done";
//#disconnect();
goto do_before_exit;
}
transitions
{
do_before_exit: goto do_before_exit;
}
}
library
digression i_am_robot
{
conditions { on #messageHasAnyIntent(digression.i_am_robot.triggers); }
var triggers = ["are_you_a_robot"];
var responses: Phrases[] = ["yes_i_am_a_robot"];
do
{
for (var item in digression.i_am_robot.responses)
{
#say(item, repeatMode: "ignore");
}
#repeat(accuracy: "short");
return;
}
transitions
{
}
}
library
preprocessor digression machine
{
conditions { on #messageHasIntent("robot_marker") || #messageHasIntent("answering_machine") priority 110000; }
var visited = 0;
do
{
$cjm.push("machine_dig");
digression disable hello;
set $conversation_result = "автоответчик";
set $status = "wait_answer";
set digression.machine.visited += 1;
if(digression.machine.visited == 2 || (digression.wait_answer.visited == 1 && digression.machine.visited == 1)) {goto do_before_exit;}
return;
//wait *;
}
transitions
{
do_before_exit: goto do_before_exit;
cantalk: goto fitness_not_qualified on timeout 5000;
/*bot: goto answering_machine on #messageHasIntent("robot_marker");
someone: goto fitness_not_qualified on true;
maybe_bot: goto answering_machine on timeout 5000;*/
}
}
digression wait_answer // дигрессии
{
conditions
{
on #messageHasIntent("robot_marker") || #messageHasIntent("answering_machine") && digression.wait_answer.visited < 3 priority 110000;
}
var visited = 0;
do
{
$cjm.push("wait_answer_dig");
digression disable hello;
set $conversation_result = "автоответчик";
set $status = "wait_answer";
set digression.wait_answer.visited += 1;
if(digression.wait_answer.visited == 2 || (digression.wait_answer.visited == 1 && digression.machine.visited == 1)) {goto do_before_exit;}
wait *;
}
transitions
{
do_before_exit: goto do_before_exit;
cantalk: goto fitness_not_qualified on timeout 5000;
/*bot: goto answering_machine on #messageHasIntent("robot_marker");
someone: goto fitness_not_qualified on true;
maybe_bot: goto answering_machine on timeout 5000;*/
}
}
/*digression ivr // дигрессии
{
conditions
{
on #messageHasIntent("robot_marker") && digression.wait_answer.visited == 0 && digression.ivr.visited < 3 priority 110000;
}
var visited = 0;
do
{
$cjm.push("ivr_dig");
set $status = "ivr";
set digression.ivr.visited += 1;
set $conversation_result = "автоответчик";
return;
}
transitions
{
}
}*/
node fitness_not_qualified
{
do
{
$cjm.push("fitness_not_qualified");
// #say("deal");
digression enable {repeat, hello};
#waitingMode(duration: 2000);
wait *;
}
transitions
{
bot: goto its_machine on #messageHasAnyIntent(["robot_marker", "answering_machine"]);
//yes: goto offer on #messageHasAnyIntent(["accept", "what_question"]) || #messageHasSentiment("positive") && !#messageHasAnyIntent(["decline", "cant_talk_rn"]);
//no_busy: goto letme_40sec on (#messageHasAnyIntent(["decline", "cant_talk_rn", "call_later"]) || #messageHasSentiment("negative")) && !#messageHasIntent("not_interested");
//time: goto been_registred on timeout 10000;
// other: goto offer on true;
}
onexit
{
}
}
node its_machine
{
do
{
$cjm.push("its_machine");
set $status = "voice_menu";
wait *;
}
transitions
{
//someone: goto fitness_not_qualified on #messageHasIntent("can_you_hear_me") priority -100;
bot: goto answering_machine on #messageHasAnyIntent(["robot_marker", "answering_machine"]);
someone: goto fitness_not_qualified on true;
maybe_bot: goto answering_machine on timeout 5000;
//targeted_action_vm_nqa_1: goto fitness_not_qualified on true;
}
}
node answering_machine
{
do
{
$cjm.push("answering_machine");
//#waitingMode(duration: 1500);
digression disable {repeat, dont_understand, can_hear_you};
set $status = "answering_machine";
goto do_before_exit;
//exit;
}
transitions
{
do_before_exit: goto do_before_exit;
//targeted_action_bot_yes: goto fitness_validation_yes;
//off_target_action_am: goto root;
}
onexit
{
default: do
{
set $conversation_result = "автоответчик";
}
}
}
\ No newline at end of file
library
preprocessor digression repeat_preprocessor
{
conditions { on true priority 50000; }
var retriesLimit=2;
var counter=0;
do
{
if (digression.repeat.resetOnRecognized)
{
set digression.repeat.counter = 0;
#log(digression.repeat.counter);
}
set digression.repeat.resetOnRecognized = true;
#log(digression.repeat.resetOnRecognized);
return;
}
transitions
{
}
}
digression repeat_hangup_params
{
conditions { on false; }
var responses: Phrases[] = ["dont_understand_hangup"];
var status = "RepeatHangup";
var serviceStatus = "Done";
do
{
}
transitions
{
}
}
digression repeat
{
conditions { on #messageHasAnyIntent(digression.repeat.triggers); }
var retriesLimit = 2;
var counter = 0;
var resetOnRecognized=false;
var triggers = ["repeat", "dont_understand", "what"];
var responses: Phrases[] = ["i_said"];
do
{
$cjm.push("repeat_dig");
if (digression.repeat.counter == digression.repeat.retriesLimit)
{
goto hangup;
}
set digression.repeat.counter = digression.repeat.counter + 1;
#log(digression.repeat.counter);
set digression.repeat.resetOnRecognized = false;
for (var item in digression.repeat.responses)
{
#say(item, repeatMode: "ignore");
}
#repeat(accuracy: "short");
return;
}
transitions
{
hangup: goto repeat_or_ping_hangup;
}
}
digression ping
{
conditions { on #messageHasAnyIntent(digression.ping.triggers) and !#messageHasIntent("greeting") priority -100; }
var retriesLimit = 2;
var counter = 0;
var resetOnRecognized=false;
var triggers = ["ping"];
do
{
$cjm.push("ping_dig");
if (digression.repeat.counter == digression.repeat.retriesLimit)
{
goto hangup;
}
set digression.repeat.counter = digression.repeat.counter + 1;
#log(digression.repeat.counter);
set digression.repeat.resetOnRecognized = false;
#repeat(accuracy: "short");
return;
}
transitions
{
hangup: goto repeat_or_ping_hangup;
}
}
node repeat_or_ping_hangup
{
do
{
$cjm.push("repeat_or_ping_hangup");
for (var item in digression.repeat_hangup_params.responses)
{
#say(item, repeatMode: "ignore");
}
set $status=digression.repeat_hangup_params.status;
set $serviceStatus=digression.repeat_hangup_params.serviceStatus;
//#disconnect();
goto do_before_exit;
}
transitions
{
do_before_exit: goto do_before_exit;
}
}
library
block doWait():doWaitMore {
start node root {
do {
#log("block 'doWait'");
wait*;
}
transitions {
transition1: goto wait_for_abonent_speech on timeout 5000;
}
}
node wait_for_abonent_speech {
do {
#sayText("Вы готовы продолжить?", repeatMode: "ignore");
wait*;
}
transitions {
yes: goto stopwaiting on #messageHasSentiment("positive") || #messageHasIntent("ready");
maybe: goto root on true && !#messageHasSentiment("positive") && !#messageHasIntent("ready") && !#messageHasSentiment("negative");
no: goto waiting on #messageHasSentiment("negative");
}
}
node waiting {
do {
#sayText("Жду.", repeatMode: "ignore");
goto root;
}
transitions{
root: goto root;
}
}
node stopwaiting {
do {
// return value from block
return "yes";
}
}
}
digression wait_for_abonent
{
conditions { on #messageHasAnyIntent(digression.wait_for_abonent.triggers); }
var triggers = ["wait", "waitfor"];
var responses: Phrases[] = ["imwaiting"];
do
{
$cjm.push("wait_for_abonent");
for (var item in digression.wait_for_abonent.responses)
{
#say(item, repeatMode: "ignore");
}
var block_result = blockcall doWait();
if (block_result == "yes")
{
#sayText("Давайте продолжим", repeatMode: "ignore");
#repeat(accuracy:"short");
return;
}
}
transitions
{
}
}
\ No newline at end of file
library
digression when_callback
{
conditions { on #messageHasIntent("when_callback") && !#messageHasIntent("notAboutCallback") priority 100; }
var responses: Phrases[] = ["willcallback"];
do
{
$cjm.push("when_callback");
for (var item in digression.when_callback.responses)
{
#say(item, repeatMode: "ignore");
//#sayText("У вас остались еще вопросы?");
}
#repeat(accuracy:"short");
return;
}
transitions
{
}
}
{
"version": "v2",
"intents": {
"accept": {
"includes": [
"да",
"ну да",
"давай",
"ага",
"угу",
"окей",
"все верно",
"правильно"
],
"excludes":[
"але",
"передавай"
]
},
"decline": {
"includes": [
"нет",
"хватит",
"не надо",
"не нужно",
"достаточно",
"отказ",
"отказываюсь"
],
"excludes":[
"может",
"надо бы",
"пока все",
"не помню"
]
},
"wait_message": {
"includes": [
"передайте",
"скажите"
]
},
"im_done": {
"includes": [
"вроде всё",
"больше ничего",
"я закончил",
"пока всё"
]
},
"ready_to_message": {
"includes": [
"давай оставим запрос",
"оставить запрос",
"оставить срочную заявку",
"хочу оставить сообщение",
"надо бы"
],
"excludes":[
]
},
"not_ready_to_message": {
"includes": [
"мне не нужен автоответчик",
"опять бот",
"мне не запрос надо, а менеджера",
"мне человек нужен прямо сейчас"
]
},
"shared_phone": {
"includes": [
"общий номер",
"это общий телефон",
"это не мой номер",
"нужен добавочный"
]
},
"not_know": {
"includes": [
"я не знаю",
"без понятия",
"кто бы знал",
"не располагаю такой информацией"
]
},
"forget": {
"includes": [
"не помню",
"не могу сейчас вспомнить",
"знаете я забыл",
"что то запамятовал"
],
"excludes":[
"я не знаю"
]
},
"agree": {
"includes": [
"можно",
"можете",
"разрешаю"
],
"excludes": [
]
},
"additional": {
"includes": [
"добавочный",
"добавочный номер"
],
"excludes":[
"я не знаю"
]
}
}
}
\ No newline at end of file
import "commonReactions/all.dsl";
context {
input phone: string;
input caller: string;
input waiting: number;
input about_abonent: string[];
input about_fields: string[];
output cjm: string[] = [];
output need_ask_name: boolean = true;
output template_id: number = 1;
output conversation_start: number = 0;
output conversation_begin: number = 0;
output conversation_stop: number = 0;
output conversation_status: string = "normal";
output conversation_result: string = "";
output abonent_request: string[] = [];
output another_phone_number: string = "";
output abonent_name: string = "";
output company_name: string = "";
output phone_suffix: string = "";
output timer: string = "";
output max_dialog_duration: number = 120000;
}
external function numbers_from_text(text: string): string;
external function dates_from_text(text: string): string;
external function part_of_the_day(): string;
external function is_empty(check: unknown): boolean;
external function sleep_ms(duration: number): unknown;
external function json_encode(object: unknown): string;
external function math_floor(value: number, presision: number|empty = 0): number;
external function math_round(value: number, presision: number|empty = 0): number;
external function math_ceil(value: number, presision: number|empty = 0): number;
external function phone_human(phone: string): string;
external function last_four(phone: string): string;
external function hours_now(): number;
external function check_mobile_code(phone: string): boolean;
external function countWords(message: string): number;
start node root
{
do
{
$cjm.push("root");
set $conversation_start = #getCurrentTime();
goto caller_id;
}
transitions
{
caller_id: goto caller_id;
}
}
block SkipMessagesBlock():boolean
{
start node root
{
do
{
return true;
}
}
}
preprocessor digression timer_control // препроцессор с проверкой истечения таймера
{
conditions
{
on true priority 100000;
}
do
{
if(#isTimerExpired($timer)){
set $conversation_result = "автоответчик";
goto do_before_exit;
}
return;
}
transitions
{
do_before_exit: goto do_before_exit;
}
}
node caller_id
{
do
{
$cjm.push("caller_id");
#connectSafe($phone);
#waitForSpeech(1000);
//таймер ограничения длинны рахговора
set $timer = #startTimer($max_dialog_duration);
// Запоминаем временной штамп перед самой первой репликой
set $conversation_begin = #getCurrentTime();
#say("greeting");
var result = blockcall SkipMessagesBlock();
wait *;
}
transitions
{
continue: goto continue on true;
}
}
node continue
{
do
{
$cjm.push("continue");
#say("greeting_2");
var result = blockcall SkipMessagesBlock();
wait*;
}
transitions
{
continue: goto offer on #messageHasAnyIntent(["what_question", "accept", "agree"]);
time: goto offer on timeout 5000;
busy: goto let_me_40sec on #messageHasAnyIntent(["cant_talk_rn", "call_later"]);
rejection: goto end_conversation_1 on #messageHasAnyIntent(["decline", "not_interested", "mistake"]);
}
onexit
{
rejection: do {
set $conversation_result = "отказ";
}
}
}
node let_me_40sec
{
do
{
$cjm.push("let_me_40sec");
#say("let_me_40sec");
var result = blockcall SkipMessagesBlock();
wait*;
}
transitions
{
agreement: goto offer on #messageHasAnyIntent(["accept", "agree"]);
rejection: goto end_conversation_2 on #messageHasIntent("decline");
}
onexit
{
rejection: do {
set $conversation_result = "перезвонить";
}
}
}
node offer
{
do
{
$cjm.push("offer");
#say("offer");
var result = blockcall SkipMessagesBlock();
wait*;
}
transitions
{
agreement: goto ask_if_client on #messageHasAnyIntent(["accept", "agree"]);
rejection: goto offer_2 on #messageHasIntent("decline");
alreagy_client: goto already_client on #messageHasIntent("already_client");
}
onexit
{
agreement: do {
set $conversation_result = "согласие";
}
}
}
node already_client
{
do
{
$cjm.push("already_client");
#say("already_client");
var result = blockcall SkipMessagesBlock();
}
transitions
{
ask_price: goto ask_price on true;
}
onexit
{
ask_price: do {
var text = #getMessageText();
#log(text);
}
}
}
node offer_2
{
do
{
$cjm.push("offer_2");
#say("offer_2");
var result = blockcall SkipMessagesBlock();
wait*;
}
transitions
{
agreement: goto ask_if_client on #messageHasAnyIntent(["accept", "agree"]);
rejection: goto end_conversation_3 on #messageHasIntent("decline");
}
onexit
{
agreement: do {
set $conversation_result = "согласие";
}
}
}
node ask_if_client
{
do
{
$cjm.push("ask_if_client");
#say("ask_if_client");
var result = blockcall SkipMessagesBlock();
wait*;
}
transitions
{
agreement: goto ask_if_satisfied on #messageHasAnyIntent(["accept", "agree"]);
rejection: goto end_conversation_4 on #messageHasIntent("decline");
why_need_it_1: goto why_need_it_1 on #messageHasIntent("why_need_it");
}
onexit
{
rejection: do {
set $conversation_result = "перезвонить";
}
}
}
node ask_if_satisfied
{
do
{
$cjm.push("ask_if_satisfied");
#say("ask_if_satisfied");
var result = blockcall SkipMessagesBlock();
wait*;
}
transitions
{
why_need_it_1: goto why_need_it_2 on #messageHasIntent("why_need_it");
ask_price: goto ask_price on true;
}
onexit
{
ask_price: do {
var text = #getMessageText();
#log(text);
}
}
}
node why_need_it_1
{
do
{
$cjm.push("why_need_it_1");
#say("why_need_it_1");
var result = blockcall SkipMessagesBlock();
wait*;
}
transitions
{
answer: goto ask_if_satisfied on true;
}
onexit
{
answer: do {
var text = #getMessageText();
#log(text);
}
}
}
node why_need_it_2
{
do
{
$cjm.push("why_need_it_2");
#say("why_need_it_2");
var result = blockcall SkipMessagesBlock();
wait*;
}
transitions
{
answer: goto answer on true;
}
onexit
{
answer: do {
var text = #getMessageText();
#log(text);
}
}
}
node answer
{
do
{
$cjm.push("answer");
#say("answer");
var result = blockcall SkipMessagesBlock();
wait*;
}
transitions
{
ask_price: goto ask_price on true;
}
onexit
{
ask_price: do {
var text = #getMessageText();
#log(text);
}
}
}
node ask_price
{
do
{
$cjm.push("ask_price");
#say("ask_price");
var result = blockcall SkipMessagesBlock();
wait*;
}
transitions
{
when_call: goto end_conversation_3 on true;
}
onexit
{
when_call: do {
var text = #getMessageText();
#log(text);
}
}
}
node end_conversation_1
{
do
{
$cjm.push("end_conversation_1");
#say("end_conversation_1");
goto do_before_exit;
}
transitions
{
do_before_exit: goto do_before_exit;
}
}
node end_conversation_2
{
do
{
$cjm.push("end_conversation_2");
#say("end_conversation_2");
goto do_before_exit;
}
transitions
{
do_before_exit: goto do_before_exit;
}
}
node end_conversation_3
{
do
{
$cjm.push("end_conversation_3");
#say("end_conversation_3");
goto do_before_exit;
}
transitions
{
do_before_exit: goto do_before_exit;
}
}
node end_conversation_4
{
do
{
$cjm.push("end_conversation_4");
#say("end_conversation_4");
goto do_before_exit;
}
transitions
{
do_before_exit: goto do_before_exit;
}
}
node do_before_exit
{
do
{
$cjm.push("do_before_exit");
set $conversation_stop = #getCurrentTime();
exit;
}
}
global digression @exit_dig_global
{
conditions { on true tags: onclosed; }
do
{
$cjm.push("@exit_dig");
set $conversation_status = "broken";
set $conversation_stop = #getCurrentTime();
exit;
}
}
{
"node::root": {
"common.position": {
"x": 600,
"y": 0
}
},
"node::caller_id": {
"common.position": {
"x": 598.377372534425,
"y": 134.60160992786908
}
},
"node::end_conversation": {
"common.position": {
"x": 600,
"y": 1090.3536507636595
}
},
"node::do_before_exit": {
"common.position": {
"x": 600,
"y": 709.2035244482049
}
},
"node::repeat_or_ping_hangup": {
"common.position": {
"x": 0,
"y": 415
}
},
"node::hello_hangup": {
"common.position": {
"x": 0,
"y": 220
}
},
"node::dont_understand_hangup": {
"common.position": {
"x": 0,
"y": 715
}
},
"node::conversation_done": {
"common.position": {
"x": 1480,
"y": 966.137946142489
}
},
"node::wait_message": {
"common.position": {
"x": 2080,
"y": 644.8260546478509
}
},
"node::get_abonent_name": {
"common.position": {
"x": 1480,
"y": 851.0084920989109
}
},
"node::check_abonent_name": {
"common.position": {
"x": 2080,
"y": 893.0535799922327
}
},
"node::say_wrote": {
"common.position": {
"x": 2080,
"y": 770.7061811030865
}
},
"node::add_message": {
"common.position": {
"x": 1480,
"y": 533.057587652757
}
},
"node::ping": {
"common.position": {
"x": 0,
"y": 315
}
},
"node::repeat": {
"common.position": {
"x": 0,
"y": 515
}
},
"node::repeat_hangup_params": {
"common.position": {
"x": 600,
"y": 530
}
},
"node::repeat_preprocessor": {
"common.position": {
"x": 600,
"y": 475
}
},
"node::hello_preprocessor": {
"common.position": {
"x": 600,
"y": 585
}
},
"node::hello": {
"common.position": {
"x": 0,
"y": 115
}
},
"node::hangup": {
"common.position": {
"x": 0,
"y": 20
}
},
"node::dont_understand_preprocessor": {
"common.position": {
"x": 600,
"y": 370
}
},
"node::dont_understand": {
"common.position": {
"x": 0,
"y": 810
}
},
"node::dont_understand_hangup_params": {
"common.position": {
"x": 600,
"y": 420
}
},
"node::can_hear_you": {
"common.position": {
"x": 600,
"y": 645
}
},
"node::exit_dig": {
"common.position": {
"x": 0,
"y": 615
}
},
"node::no_message": {
"common.position": {
"x": 1480,
"y": 734.0697783815012
}
},
"node::non_work_branch": {
"common.position": {
"x": 1046.6676796891302,
"y": 324.76777774720415
}
},
"node::request_accepted": {
"common.position": {
"x": 2680,
"y": 1029.454349255128
}
},
"node::get_client_questions": {
"common.position": {
"x": 2680,
"y": 868.8603922782834
}
},
"node::get_cell_phone": {
"common.position": {
"x": 3280,
"y": 575.5801672846062
}
},
"node::is_shared_phone": {
"common.position": {
"x": 3280,
"y": 389.5873927822081
}
},
"node::check_shared_phone": {
"common.position": {
"x": 2680,
"y": 679.7473236381277
}
},
"node::get_company_name": {
"common.position": {
"x": 2680,
"y": 224.565654864841
}
},
"node::get_another_phone": {
"common.position": {
"x": 3280,
"y": 10.131652410874324
}
},
"node::phone_confirmation": {
"common.position": {
"x": 2680,
"y": 42.55689227944265
}
},
"node::ask_client_name": {
"common.position": {
"x": 2080,
"y": 306.0375290687854
}
},
"node::check_client_name": {
"common.position": {
"x": 2080,
"y": 148.12143450145916
}
},
"node::by_work_branch": {
"common.position": {
"x": 2080,
"y": 26.98742096578726
}
},
"node::get_alter_company_name": {
"common.position": {
"x": 3280,
"y": 136.54309920643223
}
},
"node::check_mobile_code": {
"common.position": {
"x": 2680,
"y": 425.40569848894876
}
}
}
\ No newline at end of file
const fs = require("fs");
const path = require("path");
class AudioResources
{
constructor()
{
this.resources = {};
}
getResourceKey(text, voiceInfo) {
return [
voiceInfo.lang ?? "",
voiceInfo.speaker ?? "",
voiceInfo.emotion ?? "Neutral",
voiceInfo.speed ?? 1,
voiceInfo.variation ?? 0,
text,
].join("|");
}
async appendJson(folder, pack)
{
const errors = [];
let i = 0;
for (const phrase of pack.phrases ?? []) {
i++;
// валидация
if (phrase.phrase === undefined) {
errors.push(`For ${i} phrase field 'phrase' is undefined`);
continue;
}
if (phrase.audio === undefined) {
errors.push(`For ${i} phrase field 'audio' is undefined`);
continue;
}
const audioFile = path.join(folder, phrase.audio);
if (!fs.existsSync(audioFile)) {
errors.push(`For ${i} phrase '${phrase.phrase}' file not found`);
continue;
}
phrase.voice = { ...pack.voice, ...phrase.voice };
const resourceKey = this.getResourceKey(phrase.phrase, phrase.voice ?? {});
if (resourceKey in this.resources) {
// дубликат - не ошибка
console.warn("Skip", i, "phrase because it's duplicate");
continue;
}
this.resources[resourceKey] = audioFile;
}
if (errors.length > 0)
{
console.error(`Was errors: ${JSON.stringify(errors, undefined, 2)}`);
return false;
}
return true;
}
async addFolder(folder)
{
const files = fs.readdirSync(folder);
let result = false;
for (const fileName of files)
{
if (path.extname(fileName) === ".json")
{
const fname = path.join(folder, fileName);
console.log(`Parsing ${fname}`);
result = await this.appendJson(folder, JSON.parse(fs.readFileSync(fname).toString()));
}
}
return result;
}
GetPath(text, voiceInfo)
{
const key = this.getResourceKey(text, voiceInfo);
const fpath = this.resources[key];
if (fpath === undefined)
throw new Error(`Failed to get ${key}`);
return fpath;
}
}
module.exports = AudioResources;
\ No newline at end of file
module.exports = exports = {
mobile_codes() {
return [
"900", "902", "903",
"904", "905", "906",
"908", "909", "950",
"951", "953", "960",
"961", "962", "963",
"964", "965", "966",
"967", "968", "969",
"980", "983", "986",
"901", "910", "911",
"912", "913", "914",
"915", "916", "917",
"918", "919", "978",
"981", "982", "984",
"985", "987", "988",
"989", "920", "921",
"922", "923", "924",
"925", "926", "927",
"928", "929", "930",
"931", "932", "933",
"934", "936", "937",
"938", "939", "999",
"952", "958", "977",
"991", "992", "993",
"994", "995", "996"
];
}
};
\ No newline at end of file
This diff is collapsed. Click to expand it.
{
"name": "avito-test-dev",
"version": "1.0.0",
"description": "",
"author": "",
"license": "MIT",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"devDependencies": {
"prettier": "^2.3.0"
},
"dependencies": {
"string": "^3.3.3",
"moment": "^2.29.1",
"@dasha.ai/sdk": "^0.8.5"
}
}
This diff is collapsed. Click to expand it.
const axios = require("axios");
// Uncomment next URL only for authorization testing
// const api_method_send_path = "gate.smsaero.ru/v2/auth";
// Uncomment next URL for send SMS by authorized service user
const api_method_send_path = "gate.smsaero.ru/v2/sms/send";
const api_method_send = "https://" + api_method_send_path;
const api_username = 'ai@sales-mc.com';
const api_password = 'lOpVI_GrMOCe0VnUlpe9gA63nGkhmP_-';
const api_headers = { Accept: "application/json", Language: "ru-RU" };
const api_sign = "SMS Aero";
const api_auth = { username: api_username, password: api_password };
const api_options = { headers: api_headers, auth: api_auth };
module.exports = exports = {
/*
* Function for send text to abonent by Short Message Service
*
* Input params:
* number - abonent phone number from input param 'caller'
* text - text for send to abonent by Short Message Service
*
* Output params
* boolean: true|false
*
* ----------------------------------------------
* Usage in index.js for define external function
* ----------------------------------------------
*
* const sms = require("./sms-send");
*
* app.setExternal("send_sms", async (args, conv) => {
* let result = await sms.send_sms_text(args.phone, args.message);
* if (!result.success) console.log(result);
* return result.success;
* });
*
* ------------------------------------------------
* Usage in main.dsl for activate external function
* ------------------------------------------------
*
* external function send_sms(phone: string, message: string): boolean;
*
* --------------------------------------------
* Usage in any DSL for send message to abonent
* --------------------------------------------
*
* external send_sms(caller, "SMS text fo abonent");
*
*/
async send_sms_text (number, text) {
let result = {};
const params = { number: number, text: text, sign: api_sign };
let post_data = JSON.stringify(params);
api_options.params = params;
try {
result = await axios.get(api_method_send, api_options);
} catch (err) {
let error = err;
if (error.cause) error = error.cause;
if (error.response) error = {
status: error.response.status,
statusText: error.response.statusText,
method: error.response.request.method,
url: error.response.config.url,
path: error.response.request.path,
request_header: error.response.request._header,
};
result.data = {
"success": false,
"data": error,
"message": "axios crashed"
};
if (error.data) result.data = error.data;
}
return result.data;
}
}
\ No newline at end of file
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!