supersam/docs/autocall/deck_content.py

370 lines
32 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Содержание презентации «Автодозвон: как это работает».
Один источник правды: и PDF (how-it-works.py), и HTML (render-html.py) собираются
отсюда, поэтому версии не разъезжаются при правках.
Факты сверены с кодом: scripts/autocall_scheduler.py, docs/ats/ss-dialog.agi,
supabase/functions/autocall-result/index.ts и настройками боевой системы.
"""
ACCENT, ACCENT2, WARN, DANGER = "accent", "accent2", "warn", "danger"
TITLE_SLIDE = {
"kind": "title",
"kicker": "СУПЕР САМ · ДОСТАВКА И САМОВЫВОЗ",
"title": "Автодозвон: как это работает",
"sub": "Робот звонит клиенту, согласует день и половину дня — без участия оператора",
"lines": [
"Что описано: правила звонка, паузы, поведение в нештатных случаях (не дозвонились,",
"сбросили трубку, не выбрали день/время), где что настраивается и что видит менеджер.",
"",
"Основано на текущем коде и настройках боевой системы, без обещаний и продажи.",
],
}
SLIDES = [
{
"kind": "cards2full",
"title": "Что делает робот",
"sub": "Коротко: он не продаёт и не консультирует — только согласует день и половину дня",
"cards": [
{"title": "Три задачи", "accent": ACCENT, "items": [
"Дозвониться, когда заказ готов и клиент не подтвердил день по ссылке из SMS",
"Предложить конкретные дни голосом и получить выбор цифрой",
"Записать выбор в заказ — дату, половину дня и признак «согласовано роботом»",
]},
{"title": "Чего он не делает", "accent": WARN, "items": [
"Не соединяет с живым менеджером — такой цифры в диалоге нет",
"Не спорит и не уговаривает: нет ответа — повторит по расписанию",
"Не предлагает нерабочие дни и не звонит вне рабочего времени",
]},
],
"full": {"title": "Как это выглядит для клиента", "accent": ACCENT2, "items": [
"Звонок с одного номера, голос один и тот же: «Ваш заказ готов. Выберите день и время»",
"Клиент нажимает цифру дня и цифру половины дня — робот подтверждает выбор вслух",
"После подтверждения даёт возможность изменить выбор (нажатием цифры 2)",
]},
},
{
"kind": "steps",
"title": "Путь заказа до звонка",
"sub": "Когда именно звучит звонок",
"steps": [
("1. Заказ из 1С", "приходит готовым\nпо обмену"),
("2. Ссылка и SMS", "ссылка создаётся\nсама, SMS уходит"),
("3. Пауза 90 минут", "после SMS или\nпосле попытки, если\nSMS не ушло"),
("4. Звонок робота", "если клиент не\nподтвердил по ссылке"),
("5. Результат в заказ", "дата и половина дня\nв самом заказе"),
],
"full": {"title": "Важно", "accent": WARN, "items": [
"Готовность заказа приходит из 1С по обмену: заказ приходит уже готовым, вручную в системе её никто не отмечает",
"Если клиент подтвердил день по ссылке сам — звонка не будет: заказ уже согласован",
"Звонок идёт только в рабочее время и только в рабочие дни (настройки кампании)",
]},
},
{
"kind": "cards2full",
"title": "Откуда берутся дни и время",
"sub": "Админка → Расписание → Рабочие дни: один источник правды",
"cards": [
{"title": "Что настраивается", "accent": ACCENT, "items": [
"Рабочие дни склада (самовывоз) и рабочие дни доставки",
"Часы: открытие и закрытие склада, часы доставки",
"«Первая половина — до» — граница между половинами дня",
"«Сегодня предлагаем до» — до какого времени предлагать сегодняшний день",
]},
{"title": "Как это работает в коде", "accent": ACCENT2, "items": [
"Окно звонка считается рабочими днями: выходные не сокращают окно, а пропускаются",
"Робот называет реальные дни голосом: «сегодня», «в понедельник», «во вторник»",
"Клиентская ссылка использует те же дни — расхождений между звонком и ссылкой нет",
]},
],
"full": {"title": "Текущие значения в системе", "accent": WARN, "items": [
"Склад: пн–пт, 09:00–17:30, половина дня до 13:00, «сегодня» предлагаем до 15:30",
"Доставка: пн–пт (суббота — выходной) 09:00–21:00, половина дня — граница 13:00",
"Граница половины дня — 13:00 для обоих каналов: звоним после 13:00 — говорим про вторую половину дня, первую уже не предлагаем",
]},
},
{
"kind": "tablecard",
"title": "Самовывоз: какие дни предлагает",
"sub": "Окно — «день готовности + два рабочих дня», выходные пропускаются",
"table": {
"rows": [
["Заказ готов", "Что предложит робот", "Почему так"],
["в понедельник", "пн, вт, ср", "три рабочих дня подряд"],
["в пятницу", "пт, пн, вт", "суббота и воскресенье — выходные склада"],
["в пятницу после 15:30", "пн, вт", "«сегодня» больше не предлагаем (настройка)"],
["в понедельник после 13:00", "пн, вт, ср", "половину дня не спрашиваем — сразу вторая"],
["заказ готов давно", "звонка нет", "окно самовывоза прошло — звонить не о чем"],
],
"widths": [200, 240, 428],
},
"full": {"title": "Две настройки, которые это двигают", "accent": ACCENT, "items": [
"«Сегодня предлагаем до» (сейчас 15:30) — позже этого времени сегодняшний день исчезает из звонка и из ссылки",
"Граница половины дня (13:00): звоним после 13:00 — робот говорит про вторую половину дня, первую не предлагает",
]},
},
{
"kind": "tablecard",
"title": "Доставка: не в день готовности",
"sub": "Нужен запас времени, чтобы собрать маршрут — поэтому начинаем со следующего дня",
"table": {
"rows": [
["Заказ готов", "Что предложит робот"],
["в понедельник", "вторник и среда"],
["в пятницу", "понедельник и вторник (в субботу не возим)"],
["в четверг, звонок в пятницу", "пятница и понедельник"],
["в пятницу, звонок в понедельник", "понедельник и вторник"],
],
"widths": [300, 568],
},
"full": {"title": "Ключевое отличие от самовывоза", "accent": ACCENT2, "items": [
"В день готовности доставку не предлагаем никогда — только следующие рабочие дни",
"Суббота и воскресенье в графике доставки — выходные, их робот не назовёт",
"Половина дня — граница 13:00: звоним после 13:00, значит говорим про вторую половину дня",
]},
},
{
"kind": "tablecard",
"title": "Как проходит разговор",
"sub": "Робот задаёт вопрос и ждёт цифру; молчание не считается согласием",
"table": {
"rows": [
["Шаг", "Что говорит робот", "Что делает клиент", "Сколько ждёт"],
["Приветствие", "«Ваш заказ готов. Выберите день и время доставки»", "слушает", "—"],
["День", "«Нажмите один, чтобы доставить. В понедельник. Нажмите два…»", "нажимает 1 или 2", "9 секунд"],
["Половина дня", "«Первая половина дня или вторая?»", "нажимает 1 или 2", "9 секунд"],
["Подтверждение", "«Первая половина дня» — озвучивает выбор", "слушает", "—"],
["Изменить?", "подсказка про кнопку 2 — один раз", "нажимает 2, чтобы переделать", "6 секунд"],
],
"widths": [130, 360, 200, 178],
},
"full": {"title": "Что делает при ошибке ввода", "accent": WARN, "items": [
"Не понял цифру — повторяет тот же вопрос один раз",
"Снова не понял или молчит — завершает: «Вы не выбрали время. С вами свяжется менеджер»",
"Клиент нажимает 2 — диалог начинается заново («день и время»), прежний слот при этом не теряется",
]},
},
{
"kind": "tablecard",
"title": "Что можно нажать",
"sub": "Всего несколько цифр — и одна из них «больше не звоните»",
"table": {
"rows": [
["Цифра", "Значение", "Что происходит"],
["1", "первый предложенный день", "робот переходит к выбору половины дня"],
["2", "второй предложенный день", "робот переходит к выбору половины дня"],
["3", "третий день (только самовывоз)", "робот переходит к выбору половины дня"],
["1 / 2", "половина дня", "первая половина / вторая (после 13:00 — только вторая)"],
["2 после подтверждения", "изменить выбор", "робот спрашивает день и время заново — один раз"],
["любая другая цифра", "не принимается", "вопрос повторяется один раз; после двух таких звонков — менеджеру"],
],
"widths": [176, 200, 492],
},
"full": {"title": "Что происходит после подтверждения", "accent": ACCENT2, "items": [
"Робот называет выбранный день и половину дня вслух — клиент слышит, что именно записано",
"Дальше один раз предлагает изменить выбор: нажатие 2 — и день со временем спрашивают заново",
"Если клиент ничего не меняет, разговор завершается, а выбор уходит в заказ",
]},
},
{
"kind": "cards2full",
"title": "Если не дозвонились",
"sub": "Робот различает «не взял трубку» и «вместо человека ответил автоответчик/оператор»",
"cards": [
{"title": "Как понимает, что трубку не взяли", "accent": WARN, "items": [
"Никто не ответил за 45 секунд — попытка считается неудачной",
"Трубку подняли, но гудки шли больше 20 секунд и ни одной цифры не нажали — это объявление оператора, а не человек: пишем «не взял трубку»",
"Живой человек почти всегда берёт трубку раньше, поэтому правило надёжно отделяет автоответчик",
]},
{"title": "Что происходит дальше", "accent": ACCENT, "items": [
"Повторный звонок — не раньше чем через час (настройка)",
"Всего не больше 5 попыток на заказ (настройка)",
"Звонит только в рабочие часы кампании: 09:00–20:00, дни — по настройке",
"Исчерпали попытки — заказ уходит менеджеру, автозвонок по нему останавливается",
]},
],
"full": {"title": "Для менеджера это видно в карточке", "accent": ACCENT2, "items": [
"Каждая попытка — отдельная строка истории: время, результат, длительность разговора",
"Статус заказа меняется на «нужен менеджер» — с комментарием «не дозвонились / не выбрал»",
"Отдельно красным предупреждаем, если заявка «Позвонить сейчас» висит больше 15 минут",
]},
},
{
"kind": "tablecard",
"title": "Если сбросили трубку в середине разговора",
"sub": "Робот запоминает то, что успел услышать, и не портит уже согласованный слот",
"table": {
"rows": [
["Когда положили трубку", "Что запишет робот", "Что увидит менеджер"],
["до выбора дня", "ответил, день не выбрал", "«взял, не выбрал день» — попытка зачтена"],
["день выбрал, время не успел", "день выбран, время нет", "«взял, не выбрал время»"],
["выбор подтвердил и сбросил", "слот согласован", "дата и половина дня в заказе, статус «согласовано»"],
["начал менять выбор и сбросил", "остаётся прежний слот", "«правка не доведена» — прежнее согласование в силе"],
],
"widths": [250, 250, 368],
},
"full": {"title": "Почему так", "accent": ACCENT2, "items": [
"Слот становится согласованным только после двух ответов: день и половина дня — это защита от «услышал половину фразы»",
"Обрыв не считается согласием: если клиент не подтвердил, робот перезвонит по расписанию или отдаст заказ менеджеру",
"Если клиент уже согласовал слот, а потом начал менять и бросил трубку — прежний выбор сохраняется, ничего не теряется",
]},
},
{
"kind": "tablecard",
"title": "Клиент не выбрал дату после приглашения",
"sub": "Срок ожидания считаем от последнего контакта — SMS или звонка робота",
"table": {
"rows": [
["Что настроено в системе", "От чего считаем срок", "Когда заказ уходит менеджеру"],
["Только SMS-приглашение", "от последнего SMS", "через 3 ч (настройка в админке)"],
["Плюс автодозвон", "ждём звонок робота, отсчёт — от него", "через 3 ч после последнего звонка"],
["Плюс второе приглашение", "сначала ждём второе SMS, потом звонок", "после последнего контакта по последнему каналу"],
["Звонить нельзя (гео, исключение, «не звонить»)", "от последнего SMS", "через 3 ч — звонок не ждём"],
],
"widths": [250, 300, 318],
},
"full": {"title": "Что важно", "accent": ACCENT2, "items": [
"Ожидание включается только по каналам, которые реально включены в системе: если автодозвона нет — не ждём звонок",
"Позвонили позже — ожидание начинается заново: менеджер получает заказ, только когда клиент молчит по всем каналам",
"Клиент выбрал дату — из ожидания выходим сразу, даже если срок не истёк",
]},
},
{
"kind": "cards3full",
"title": "Когда подключается менеджер",
"sub": "Робот доводит дело до конца сам, но в трёх случаях передаёт человеку",
"cards": [
{"title": "Не выбрал день/время 2 раза", "accent": WARN, "items": [
"Робот дважды фиксировал «взял, но не выбрал»",
"Заказ помечается «нужен менеджер», комментарий «не дозвонились / не выбрал»",
"Порог «не выбрал × N» настраивается в админке автодозвона",
]},
{"title": "Исчерпаны 5 попыток", "accent": WARN, "items": [
"Каждый звонок — отдельная попытка",
"Когда попытки закончились, автозвонок прекращается",
"Заказ остаётся в списке у менеджера",
]},
{"title": "Неверный номер", "accent": DANGER, "items": [
"Если номер не существует или недоступен — задача менеджеру",
"Менеджер может поставить «Не звонить» — тогда робот этого клиента не беспокоит",
"Такая отметка видна в карточке заказа и учитывается при обзвоне",
]},
],
"full": {"title": "Что видит менеджер в карточке заказа", "accent": ACCENT, "items": [
"Единый статус автодозвона и история всех попыток с результатами и слотами",
"Кнопка «Позвонить сейчас» — ручной звонок клиенту (не тестовый номер) и живое состояние: «в очереди», «звоним», «звонок сделан» с результатом",
"Кнопка «Не звонить» — если робот не должен беспокоить этого клиента",
]},
},
{
"kind": "cards2full",
"title": "Когда робот не звонит вообще",
"sub": "Список условий, при которых звонка не будет — проверяются до набора номера",
"cards": [
{"title": "По клиенту и заказу", "accent": ACCENT, "items": [
"Клиент сам подтвердил день по ссылке — звонок не нужен",
"Менеджер поставил «Не звонить» — робот этого клиента не беспокоит",
"Номер в списке исключений — например, на МТС-диапазон звонки не идут",
"Самовывоз: автообзвон по самовывозу включается отдельной галочкой (сейчас выключен)",
]},
{"title": "По времени и географии", "accent": WARN, "items": [
"Вне рабочих часов кампании (09:00–20:00) и вне рабочих дней",
"Город исключён целиком или для города выключен канал",
"В админке автодозвона выключены звонки по городу — например, Ялта: SMS идут, звонков нет",
"Меньше 90 минут прошло после последней попытки отправки SMS: если приглашение ушло — считаем от отправки, если не ушло — от попытки",
]},
],
"full": {"title": "Админка автодозвона: где это переключается", "accent": ACCENT2, "items": [
"Панель «Автодозвон»: тестовый режим, часы и дни звонков, паузы, лимит попыток, порог «не выбрал × N»",
"Панель «Локации»: для каждого города — звонки включены или выключены (SMS не затрагивается)",
"Панель исключений: номера и префиксы, на которые не звоним, с причиной",
]},
},
{
"kind": "tablecard",
"title": "Что записывается в заказ",
"sub": "Результат звонка виден там же, где всё остальное",
"table": {
"rows": [
["Поле", "Значение"],
["Дата", "конкретная дата, которую назвал робот (например, понедельник 21.09)"],
["Время", "«первая половина дня» или «вторая половина дня»"],
["Источник", "«согласовано роботом» — видно, что выбор сделал клиент в звонке"],
["Статус", "«согласовано» / «нужен менеджер» / «не звонить» (запрет ставит менеджер)"],
["Комментарий", "«Согласовано роботом: завтра, первая половина дня»"],
],
"widths": [200, 668],
},
"full": {"title": "Зачем это нужно", "accent": ACCENT, "items": [
"Менеджер видит причину и источник решения, а не просто «дата стоит»",
"История звонков хранится отдельно: видно, сколько было попыток и чем они закончились",
"Дата, названная роботом, используется дальше в работе склада и доставки",
]},
},
{
"kind": "tablecard",
"title": "Тестовый режим и текущее состояние",
"sub": "Сейчас обзвон клиентов выключен — система в тестовом режиме",
"table": {
"rows": [
["Параметр", "Значение сейчас", "Что будет при запуске"],
["Обзвон клиентов", "выключен", "включается отдельной командой"],
["Тестовый номер", "звонит только на него", "массовый обзвон идёт клиентам"],
["Кнопка «Позвонить сейчас»", "звонит клиенту сразу", "так же — звонок клиенту"],
["Звонки по самовывозу", "выключены галочкой", "включаются отдельно от доставки"],
],
"widths": [230, 280, 358],
},
"full": {"title": "Как проверяется перед запуском", "accent": ACCENT2, "items": [
"Тестовый звонок на свой номер: диалог, дни, половина дня, запись результата",
"Прогон диалога без звонка: проверка всех веток (согласие, обрыв, молчание, отказ)",
"Проверка окон: робот предлагает именно те дни, которые заданы в админке",
]},
},
{
"kind": "cards2full",
"title": "Что пока не учитывается",
"sub": "Честный список: это важно знать до запуска",
"cards": [
{"title": "График", "accent": WARN, "items": [
"Праздники: календаря нерабочих дат нет — если праздник попадёт в окно, робот его предложит",
"Часы доставки используются частично: границу половины дня робот проговаривает словами, без конкретного времени",
]},
{"title": "Настройки, которые пока не влияют", "accent": DANGER, "items": [
"«Попыток в день» — поле есть, но расписание повторов задаётся интервалом между попытками",
"«Попытки следующего дня (10:00, 14:00)» — пока не используются",
"«Таймаут звонка, 30 секунд» — звонок ждёт ответа 45 секунд (значение в самом звонке)",
]},
],
"full": {"title": "Что предлагаем уточнить до боевого запуска", "accent": ACCENT2, "items": [
"Список праздников (или решение не учитывать их)",
"Нужен ли жёсткий график повторов по времени, кроме паузы в час",
"Кто и когда разбирает заказы, которые робот не согласовал за 5 попыток",
]},
},
{
"kind": "cards2full",
"title": "Коротко",
"sub": "Одна страница вместо всей презентации",
"cards": [
{"title": "Что делает система", "accent": ACCENT, "full": True, "dense": True, "items": [
"Ждёт 90 минут после SMS (или после последней попытки отправки, если SMS не ушло) и звонит, если клиент не подтвердил день сам",
"Предлагает только рабочие дни по графику: самовывоз — включая сегодня, доставка — со следующего дня",
"Спрашивает день и половину дня, подтверждает вслух, даёт один раз переделать выбор",
"Граница половины дня — 13:00: звоним после 13:00, значит говорим про вторую половину",
"Повторяет попытки не чаще чем раз в час, максимум 5 раз, только 09:00–20:00 в рабочие дни",
"После двух «взял, но не выбрал» или исчерпания попыток передаёт заказ менеджеру",
"Каждая попытка и результат видны в карточке заказа; ручной звонок идёт клиенту и показывает своё состояние",
]},
],
"full": {"title": "Что осталось решить", "accent": WARN, "items": [
"Праздники и точный график повторов — по вашим правилам",
"Момент включения боевого обзвона клиентов и по самовывозу",
]},
},
]
ALL_SLIDES = [TITLE_SLIDE] + SLIDES