fix(autocall): убраны сценарии «0» и «9» из диалога и из презентации; пауза между звонками 1 час; граница половины дня 13:00; в презентации готовность по обмену с 1С, без готовности в субботу
This commit is contained in:
parent
833d2dcd44
commit
aeb4bbf63f
|
|
@ -64,7 +64,7 @@ on_interrupt () {
|
|||
if [ -z "$OUTCOME" ]; then
|
||||
if [ -n "$HALF" ]; then
|
||||
OUTCOME=no_input_half # день выбрал, время не назвал
|
||||
elif [ -n "$DAY" ] && [ "$DAY" != "0" ] && [ "$DAY" != "9" ]; then
|
||||
elif [ -n "$DAY" ] && [ "$DAY" != "0" ]; then
|
||||
OUTCOME=no_input_half # день выбран, до времени не дошло
|
||||
elif [ -z "$ANY_DIGIT" ] && [ "$RING_SEC" -ge 20 ]; then
|
||||
OUTCOME=no_answer # объявление оператора: человека не было
|
||||
|
|
@ -114,7 +114,7 @@ save () {
|
|||
# Отправляем в БД сразу при финальном исходе (клиент может бросить трубку
|
||||
# в любой момент — результат должен успеть уйти). Идемпотентность по uniqueid.
|
||||
case "$OUTCOME" in
|
||||
confirmed|confirmed_kept_previous|confirmed_silent|no_answer|no_input_day|no_input_half|operator|opt_out|invalid_number|error)
|
||||
confirmed|confirmed_kept_previous|confirmed_silent|no_answer|no_input_day|no_input_half|operator|invalid_number|error)
|
||||
send_result ;;
|
||||
esac
|
||||
}
|
||||
|
|
@ -236,7 +236,6 @@ if [ "$TYPE" = "pkp" ] && [ -n "$PICKUP_DAY1" ]; then
|
|||
fi
|
||||
CHOSEN_DAY=$DIGIT
|
||||
case "$CHOSEN_DAY" in
|
||||
9) play "ru/ss_optout"; OUTCOME=opt_out; break ;;
|
||||
1|2|3) [ "$CHOSEN_DAY" -le "$DAYS" ] || CHOSEN_DAY="" ;;
|
||||
*) CHOSEN_DAY="" ;;
|
||||
esac
|
||||
|
|
@ -320,7 +319,6 @@ if [ "$TYPE" = "dlv" ] && [ -n "$DELIVERY_DAY1" ]; then
|
|||
wait_digit 9000
|
||||
CHOSEN_DAY=$DIGIT
|
||||
case "$CHOSEN_DAY" in
|
||||
9) play "ru/ss_optout"; OUTCOME=opt_out; break ;;
|
||||
1|2) [ "$CHOSEN_DAY" -le "$DLV_DAYS" ] || CHOSEN_DAY="" ;;
|
||||
*) CHOSEN_DAY="" ;;
|
||||
esac
|
||||
|
|
@ -373,7 +371,7 @@ while [ -z "$OUTCOME" ]; do
|
|||
if [ "$SCENARIO" = "A" ]; then
|
||||
digit "ru/ss_a_day_${TYPE}"
|
||||
DAY=$DIGIT
|
||||
if [ "$DAY" != "1" ] && [ "$DAY" != "2" ] && [ "$DAY" != "0" ] && [ "$DAY" != "9" ]; then
|
||||
if [ "$DAY" != "1" ] && [ "$DAY" != "2" ] && [ "$DAY" != "0" ]; then
|
||||
digit "ru/ss_a_day_${TYPE}"
|
||||
DAY=$DIGIT
|
||||
fi
|
||||
|
|
@ -382,9 +380,7 @@ while [ -z "$OUTCOME" ]; do
|
|||
fi
|
||||
save
|
||||
|
||||
if [ "$DAY" = "9" ]; then
|
||||
play "ru/ss_optout"; OUTCOME=opt_out; break
|
||||
elif [ "$DAY" != "1" ] && [ "$DAY" != "2" ]; then
|
||||
if [ "$DAY" != "1" ] && [ "$DAY" != "2" ]; then
|
||||
if [ -z "$ANY_DIGIT" ] && [ "$RING_SEC" -ge 20 ]; then
|
||||
OUTCOME=no_answer; break # объявление оператора, человека не было
|
||||
fi
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Binary file not shown.
|
|
@ -81,8 +81,8 @@ SLIDES = [
|
|||
],
|
||||
"full": {"title": "Текущие значения в системе", "accent": WARN, "items": [
|
||||
"Склад: пн–пт, 09:00–17:30, половина дня до 13:00, «сегодня» предлагаем до 15:30",
|
||||
"Доставка: пн–пт (суббота — выходной) 09:00–21:00, половина дня до 15:00",
|
||||
"Утро и вечер: до 13:00 робот спросит, какая половина дня удобнее; после 13:00 — сразу зафиксирует вторую",
|
||||
"Доставка: пн–пт (суббота — выходной) 09:00–21:00, половина дня — граница 13:00",
|
||||
"Граница половины дня — 13:00 для обоих каналов: звоним после 13:00 — говорим про вторую половину дня, первую уже не предлагаем",
|
||||
]},
|
||||
},
|
||||
{
|
||||
|
|
@ -94,16 +94,15 @@ SLIDES = [
|
|||
["Заказ готов", "Что предложит робот", "Почему так"],
|
||||
["в понедельник", "пн, вт, ср", "три рабочих дня подряд"],
|
||||
["в пятницу", "пт, пн, вт", "суббота и воскресенье — выходные склада"],
|
||||
["в субботу", "пн, вт, ср", "сам выходной не предлагаем"],
|
||||
["в пятницу после 15:30", "пн, вт", "«сегодня» больше не предлагаем (настройка)"],
|
||||
["в понедельник после 13:00", "пн, вт, ср", "половину дня не спрашиваем — сразу вторая"],
|
||||
["неделю назад", "звонка нет", "окно прошло — звонить не о чем"],
|
||||
["заказ готов давно", "звонка нет", "окно самовывоза прошло — звонить не о чем"],
|
||||
],
|
||||
"widths": [200, 240, 428],
|
||||
},
|
||||
"full": {"title": "Две настройки, которые это двигают", "accent": ACCENT, "items": [
|
||||
"«Сегодня предлагаем до» (сейчас 15:30) — позже этого времени сегодняшний день исчезает из звонка и из ссылки",
|
||||
"«Первая половина — до» (сейчас 13:00) — после неё робот не спрашивает половину дня, сразу пишет вторую",
|
||||
"Граница половины дня (13:00): звоним после 13:00 — робот говорит про вторую половину дня, первую не предлагает",
|
||||
]},
|
||||
},
|
||||
{
|
||||
|
|
@ -115,7 +114,6 @@ SLIDES = [
|
|||
["Заказ готов", "Что предложит робот"],
|
||||
["в понедельник", "вторник и среда"],
|
||||
["в пятницу", "понедельник и вторник (в субботу не возим)"],
|
||||
["в субботу", "понедельник и вторник"],
|
||||
["в четверг, звонок в пятницу", "пятница и понедельник"],
|
||||
["в пятницу, звонок в понедельник", "понедельник и вторник"],
|
||||
],
|
||||
|
|
@ -124,7 +122,7 @@ SLIDES = [
|
|||
"full": {"title": "Ключевое отличие от самовывоза", "accent": ACCENT2, "items": [
|
||||
"В день готовности доставку не предлагаем никогда — только следующие рабочие дни",
|
||||
"Суббота и воскресенье в графике доставки — выходные, их робот не назовёт",
|
||||
"Время доставки — половина дня: до 15:00 или после (границу задаёт админка)",
|
||||
"Половина дня — граница 13:00: звоним после 13:00, значит говорим про вторую половину дня",
|
||||
]},
|
||||
},
|
||||
{
|
||||
|
|
@ -158,15 +156,16 @@ SLIDES = [
|
|||
["1", "первый предложенный день", "робот переходит к выбору половины дня"],
|
||||
["2", "второй предложенный день", "робот переходит к выбору половины дня"],
|
||||
["3", "третий день (только самовывоз)", "робот переходит к выбору половины дня"],
|
||||
["1 / 2", "половина дня", "первая половина / вторая половина"],
|
||||
["9", "отказ от звонков", "робот больше не позвонит; в карточке — «отказ от звонков»"],
|
||||
["0 и прочие", "не принимаются", "вопрос повторяется; соединения с оператором нет"],
|
||||
["1 / 2", "половина дня", "первая половина / вторая (после 13:00 — только вторая)"],
|
||||
["2 после подтверждения", "изменить выбор", "робот спрашивает день и время заново — один раз"],
|
||||
["любая другая цифра", "не принимается", "вопрос повторяется один раз; после двух таких звонков — менеджеру"],
|
||||
],
|
||||
"widths": [110, 240, 518],
|
||||
"widths": [176, 200, 492],
|
||||
},
|
||||
"full": {"title": "Отдельно про «0»", "accent": DANGER, "items": [
|
||||
"Раньше в диалоге была попытка «позвать менеджера», но она никогда не срабатывала (нажатие не отличалось от тишины)",
|
||||
"Эту ветку убрали: живого соединения с оператором у робота нет, менеджер подключается только задачей из системы",
|
||||
"full": {"title": "Что происходит после подтверждения", "accent": ACCENT2, "items": [
|
||||
"Робот называет выбранный день и половину дня вслух — клиент слышит, что именно записано",
|
||||
"Дальше один раз предлагает изменить выбор: нажатие 2 — и день со временем спрашивают заново",
|
||||
"Если клиент ничего не меняет, разговор завершается, а выбор уходит в заказ",
|
||||
]},
|
||||
},
|
||||
{
|
||||
|
|
@ -180,7 +179,7 @@ SLIDES = [
|
|||
"Живой человек почти всегда берёт трубку раньше, поэтому правило надёжно отделяет автоответчик",
|
||||
]},
|
||||
{"title": "Что происходит дальше", "accent": ACCENT, "items": [
|
||||
"Повторный звонок — не раньше чем через 120 минут (настройка)",
|
||||
"Повторный звонок — не раньше чем через час (настройка)",
|
||||
"Всего не больше 5 попыток на заказ (настройка)",
|
||||
"Звонит только в рабочие часы кампании: 09:00–20:00, дни — по настройке",
|
||||
"Исчерпали попытки — заказ уходит менеджеру, автозвонок по нему останавливается",
|
||||
|
|
@ -227,10 +226,10 @@ SLIDES = [
|
|||
"Когда попытки закончились, автозвонок прекращается",
|
||||
"Заказ остаётся в списке у менеджера",
|
||||
]},
|
||||
{"title": "Отказ или неверный номер", "accent": DANGER, "items": [
|
||||
"Цифра 9 — клиент просит больше не звонить: ставим запрет автоматически",
|
||||
"Неверный номер — задача менеджеру",
|
||||
"Отказ клиента действует и на другие заказы: он в списке «не звонить»",
|
||||
{"title": "Неверный номер", "accent": DANGER, "items": [
|
||||
"Если номер не существует или недоступен — задача менеджеру",
|
||||
"Менеджер может поставить «Не звонить» — тогда робот этого клиента не беспокоит",
|
||||
"Такая отметка видна в карточке заказа и учитывается при обзвоне",
|
||||
]},
|
||||
],
|
||||
"full": {"title": "Что видит менеджер в карточке заказа", "accent": ACCENT, "items": [
|
||||
|
|
@ -246,7 +245,7 @@ SLIDES = [
|
|||
"cards": [
|
||||
{"title": "По клиенту и заказу", "accent": ACCENT, "items": [
|
||||
"Клиент сам подтвердил день по ссылке — звонок не нужен",
|
||||
"Клиент просил больше не звонить (нажал 9) или менеджер поставил «Не звонить»",
|
||||
"Менеджер поставил «Не звонить» — робот этого клиента не беспокоит",
|
||||
"Номер в списке исключений — например, на МТС-диапазон звонки не идут",
|
||||
"Самовывоз: автообзвон по самовывозу включается отдельной галочкой (сейчас выключен)",
|
||||
]},
|
||||
|
|
@ -273,7 +272,7 @@ SLIDES = [
|
|||
["Дата", "конкретная дата, которую назвал робот (например, понедельник 21.09)"],
|
||||
["Время", "«первая половина дня» или «вторая половина дня»"],
|
||||
["Источник", "«согласовано роботом» — видно, что выбор сделал клиент в звонке"],
|
||||
["Статус", "«согласовано» / «нужен менеджер» / «отказ от звонков»"],
|
||||
["Статус", "«согласовано» / «нужен менеджер» / «не звонить» (запрет ставит менеджер)"],
|
||||
["Комментарий", "«Согласовано роботом: завтра, первая половина дня»"],
|
||||
],
|
||||
"widths": [200, 668],
|
||||
|
|
@ -321,8 +320,8 @@ SLIDES = [
|
|||
],
|
||||
"full": {"title": "Что предлагаем уточнить до боевого запуска", "accent": ACCENT2, "items": [
|
||||
"Список праздников (или решение не учитывать их)",
|
||||
"Нужен ли жёсткий график повторов по времени, кроме интервала 120 минут",
|
||||
"Оставить ли «0» без реакции — сейчас это просто неверная цифра",
|
||||
"Нужен ли жёсткий график повторов по времени, кроме паузы в час",
|
||||
"Кто и когда разбирает заказы, которые робот не согласовал за 5 попыток",
|
||||
]},
|
||||
},
|
||||
{
|
||||
|
|
@ -334,9 +333,9 @@ SLIDES = [
|
|||
"Ждёт 90 минут после SMS и звонит, если клиент не подтвердил день сам",
|
||||
"Предлагает только рабочие дни по графику: самовывоз — включая сегодня, доставка — со следующего дня",
|
||||
"Спрашивает день и половину дня, подтверждает вслух, даёт один раз переделать выбор",
|
||||
"Повторяет попытки не чаще чем раз в 2 часа, максимум 5 раз, только 09:00–20:00 в рабочие дни",
|
||||
"Граница половины дня — 13:00: звоним после 13:00, значит говорим про вторую половину",
|
||||
"Повторяет попытки не чаще чем раз в час, максимум 5 раз, только 09:00–20:00 в рабочие дни",
|
||||
"После двух «взял, но не нажал» или исчерпания попыток передаёт заказ менеджеру",
|
||||
"Отказ (цифра 9) останавливает обзвон клиента навсегда",
|
||||
"Каждая попытка и результат видны в карточке заказа; ручной звонок идёт клиенту и показывает своё состояние",
|
||||
]},
|
||||
],
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ const OUTCOMES = new Set([
|
|||
"no_input_day",
|
||||
"no_input_half",
|
||||
"operator",
|
||||
"opt_out",
|
||||
"invalid_number",
|
||||
"error",
|
||||
]);
|
||||
|
|
@ -196,7 +195,7 @@ Deno.serve(async (request) => {
|
|||
await supabase.from("order_groups").update(update).eq("id", orderGroupId);
|
||||
}
|
||||
// ── Эскалация ──
|
||||
else if (["operator", "opt_out", "invalid_number"].includes(body.outcome)) {
|
||||
else if (["operator", "invalid_number"].includes(body.outcome)) {
|
||||
const update: Record<string, unknown> = {
|
||||
notification_status: "manual_required",
|
||||
called: true,
|
||||
|
|
@ -204,11 +203,8 @@ Deno.serve(async (request) => {
|
|||
called_comment:
|
||||
body.outcome === "operator"
|
||||
? "Просил менеджера"
|
||||
: body.outcome === "opt_out"
|
||||
? "Отказался от автозвонков"
|
||||
: "Неверный номер",
|
||||
: "Неверный номер",
|
||||
};
|
||||
if (body.outcome === "opt_out") update.autocall_opt_out = true;
|
||||
await supabase.from("order_groups").update(update).eq("id", orderGroupId);
|
||||
}
|
||||
// ── no_answer / no_input: решаем, эскалировать ли ──
|
||||
|
|
|
|||
Loading…
Reference in New Issue