feat(jivo-bot): эскалация = просьба телефона + письмо с контактом в поддержку
Правило владельца 12.07.2026: оператора в чате может не быть, поэтому бот НЕ переводит диалог (INVITE_AGENT убран из авто-флоу). Не смог ответить (личный вопрос, стоп-тема, незнание) → просит номер телефона → как только клиент его оставил, контакт уходит письмом в поддержку, а клиенту — «Спасибо, передал». - ContactCapture: распознаёт номер в любом формате (+7/8/скобки/дефисы) → 79161234567 - BotContactRequestMail + шаблон: телефон, вопрос-на-котором-спасовал, id чата, переписка целиком, время → services.support.email - ProcessJivoMessageJob: ждём контакт, если прошлый ответ бота просил номер; номера нет (клиент передумал/спросил другое) — отвечаем как обычно - тексты эскалации переписаны под сбор контакта TDD: BotContactCaptureTest (4 новых) + обновлены 4 теста прежней механики. 46/46. Живая проверка на стенде: вопрос → просьба → номер → письмо с полной перепиской. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -43,12 +43,16 @@ it('happy path: ответ уходит в Jivo, журнал пишет in+out
|
||||
->and($out->matched_chunks)->not->toBeNull();
|
||||
});
|
||||
|
||||
it('эскалация: BOT_MESSAGE-прощание + INVITE_AGENT, журнал escalated=true', function () {
|
||||
it('эскалация: просьба телефона в чат, БЕЗ перевода на оператора, журнал escalated=true', function () {
|
||||
// Правило владельца 12.07.2026: оператора в чате может не быть — бот собирает контакт
|
||||
// сам и отдаёт его поддержке письмом (см. BotContactCaptureTest).
|
||||
Http::fake(['bot.jivosite.com/*' => Http::response(['ok' => true])]);
|
||||
|
||||
(new ProcessJivoMessageJob('chat-2', 'client-2', 'какой у меня баланс?'))->handle();
|
||||
|
||||
Http::assertSent(fn ($r) => ($r['event'] ?? '') === 'INVITE_AGENT');
|
||||
Http::assertNotSent(fn ($r) => ($r['event'] ?? '') === 'INVITE_AGENT');
|
||||
Http::assertSent(fn ($r) => ($r['event'] ?? '') === 'BOT_MESSAGE'
|
||||
&& str_contains($r['message']['text'], 'номер телефона'));
|
||||
expect(BotDialog::where('direction', 'out')->firstOrFail()->escalated)->toBeTrue();
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user