Files
libredesk/internal/conversation/transcript.go
Abhinav Raut 170fcd026d add help article citations to AI replies
Link cited public help articles in chat replies and emails. Batch reference lookups and keep source metadata out of customer replies.
2026-10-10 20:57:12 +05:30

73 lines
2.5 KiB
Go

package conversation
import (
"fmt"
"strings"
"time"
"github.com/abhinavxd/libredesk/internal/conversation/models"
"github.com/abhinavxd/libredesk/internal/stringutil"
)
const (
transcriptTimeFormat = "Jan 02, 2006 03:04 PM MST"
transcriptSeparator = "------------------------------------------------------------"
)
func (m *Manager) BuildTranscript(conversation models.Conversation, messages []models.Message, downloadedAt time.Time) []byte {
var b strings.Builder
fmt.Fprintf(&b, "%s #%s\n", m.i18n.T("globals.terms.conversation"), conversation.ReferenceNumber)
if subject := conversation.Subject.String; subject != "" {
fmt.Fprintf(&b, "%s: %s\n", m.i18n.T("globals.terms.subject"), subject)
}
if contact := conversation.Contact.FullName(); contact != "" {
fmt.Fprintf(&b, "%s: %s\n", m.i18n.T("globals.terms.contact"), contact)
}
fmt.Fprintf(&b, "%s: %s\n", m.i18n.T("globals.terms.createdAt"), conversation.CreatedAt.UTC().Format(transcriptTimeFormat))
fmt.Fprintf(&b, "%s: %s\n\n", m.i18n.T("globals.terms.downloadedAt"), downloadedAt.UTC().Format(transcriptTimeFormat))
b.WriteString(transcriptSeparator + "\n")
label := m.i18n.Tc("globals.terms.articleReference", 2 /* n */)
references := m.lookupArticleReferences(messageMetas(messages)...)
for i, message := range messages {
content := message.TextContent
if content == "" {
content = stringutil.HTML2Text(message.Content)
}
if len(references[i]) > 0 {
content += "\n\n" + stringutil.HTML2TextMarkdownLinks(articleReferencesHTML(references[i], label))
}
fmt.Fprintf(&b, "\n[%s] %s (%s):\n%s\n",
message.CreatedAt.UTC().Format(transcriptTimeFormat),
transcriptAuthor(message),
m.senderTypeLabel(message.SenderType),
content,
)
if len(message.Attachments) > 0 {
names := make([]string, 0, len(message.Attachments))
for _, attachment := range message.Attachments {
names = append(names, attachment.Name)
}
fmt.Fprintf(&b, "%s: %s\n", m.i18n.Tc("globals.terms.attachment", len(message.Attachments)), strings.Join(names, ", "))
}
}
return []byte(b.String())
}
func (m *Manager) senderTypeLabel(senderType string) string {
switch senderType {
case models.SenderTypeAgent:
return m.i18n.T("globals.terms.agent")
case models.SenderTypeContact:
return m.i18n.T("globals.terms.contact")
}
return senderType
}
func transcriptAuthor(message models.Message) string {
if sender := proactiveSender(message.Meta); sender != "" {
return sender
}
return message.Author.FullName()
}