mirror of
https://github.com/abhinavxd/libredesk.git
synced 2026-09-11 21:39:00 +00:00
send AI verification code through the conversation's inbox
The OTP email went out over the notification email channel, which uses a separate SMTP config and a different sender. Now email conversations send the code through their own inbox, reusing the conversation subject so it threads into the same email thread instead of a new one. Livechat still falls back to the notification channel since it can't send email.
This commit is contained in:
@@ -249,14 +249,27 @@ func (t *sendEmailVerificationTool) Execute(ctx context.Context, args string) (s
|
||||
return "", err
|
||||
}
|
||||
body := t.m.i18n.Ts("ai.agent.verificationEmailBody", "code", code)
|
||||
if err := t.m.notifier.Send(notifier.Message{
|
||||
RecipientEmails: []string{email},
|
||||
Subject: t.m.i18n.T("ai.agent.verificationEmailSubject"),
|
||||
Content: body,
|
||||
Provider: notifier.ProviderEmail,
|
||||
}); err != nil {
|
||||
t.m.lo.Error("error sending verification code email", "conversation_uuid", t.conv.UUID, "error", err)
|
||||
return "", err
|
||||
// Livechat inboxes can't send email, so those fall back to the notification email channel.
|
||||
var sendErr error
|
||||
if t.conv.InboxChannel == channelEmail {
|
||||
// Reuse the conversation's subject so the code threads into the same email thread instead of
|
||||
// landing in a separate one the customer might reply to.
|
||||
subject := t.conv.Subject.String
|
||||
if subject == "" {
|
||||
subject = t.m.i18n.T("ai.agent.verificationEmailSubject")
|
||||
}
|
||||
sendErr = t.m.convo.SendTransientEmail(t.conv.InboxID, t.conv.ID, t.conv.UUID, []string{email}, subject, body)
|
||||
} else {
|
||||
sendErr = t.m.notifier.Send(notifier.Message{
|
||||
RecipientEmails: []string{email},
|
||||
Subject: t.m.i18n.T("ai.agent.verificationEmailSubject"),
|
||||
Content: body,
|
||||
Provider: notifier.ProviderEmail,
|
||||
})
|
||||
}
|
||||
if sendErr != nil {
|
||||
t.m.lo.Error("error sending verification code email", "conversation_uuid", t.conv.UUID, "error", sendErr)
|
||||
return "", sendErr
|
||||
}
|
||||
t.m.lo.Debug("ai agent sent verification code", "conversation_uuid", t.conv.UUID)
|
||||
return "A verification code has been emailed to the customer. Tell them you have sent a code to their email and ask them to reply with it.", nil
|
||||
|
||||
@@ -1140,6 +1140,27 @@ func (m *Manager) BuildEmailThreadingHeaders(conversationID int, selfSourceID st
|
||||
return references, inReplyTo
|
||||
}
|
||||
|
||||
// SendTransientEmail sends a one-off email through the conversation's inbox, threaded like a reply, without recording it as a conversation message.
|
||||
func (m *Manager) SendTransientEmail(inboxID, conversationID int, conversationUUID string, to []string, subject, htmlContent string) error {
|
||||
inb, err := m.inboxStore.Get(inboxID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("fetching inbox: %w", err)
|
||||
}
|
||||
if inb.Channel() != inbox.ChannelEmail {
|
||||
return fmt.Errorf("cannot send email through non-email inbox %d", inboxID)
|
||||
}
|
||||
references, inReplyTo := m.BuildEmailThreadingHeaders(conversationID, "")
|
||||
return inb.Send(models.OutboundMessage{
|
||||
From: inb.FromAddress(),
|
||||
To: to,
|
||||
Subject: subject,
|
||||
Content: htmlContent,
|
||||
ConversationUUID: conversationUUID,
|
||||
References: references,
|
||||
InReplyTo: inReplyTo,
|
||||
})
|
||||
}
|
||||
|
||||
// NotifyAssignment sends notifications (in-app, WebSocket, email) for an assigned conversation.
|
||||
func (m *Manager) NotifyAssignment(userIDs []int, conversation models.Conversation) error {
|
||||
agent, err := m.userStore.GetAgent(userIDs[0], "")
|
||||
|
||||
Reference in New Issue
Block a user