feat(search): align conversation result payloads
This commit is contained in:
@@ -318,27 +318,127 @@ func serializeSearchConversations(results []search.SearchResult) []map[string]an
|
||||
|
||||
func serializeSearchConversation(result search.SearchResult) map[string]any {
|
||||
if conv, ok := result.Data.(model.Conversation); ok {
|
||||
return map[string]any{
|
||||
"id": conversationDisplayID(&conv),
|
||||
"account_id": conv.AccountID,
|
||||
"created_at": conv.CreatedAt.Unix(),
|
||||
"additional_attributes": jsonObject(conv.AdditionalAttributes),
|
||||
}
|
||||
return serializeSearchConversationModel(&conv)
|
||||
}
|
||||
if conv, ok := result.Data.(*model.Conversation); ok && conv != nil {
|
||||
return map[string]any{
|
||||
"id": conversationDisplayID(conv),
|
||||
"account_id": conv.AccountID,
|
||||
"created_at": conv.CreatedAt.Unix(),
|
||||
"additional_attributes": jsonObject(conv.AdditionalAttributes),
|
||||
}
|
||||
return serializeSearchConversationModel(conv)
|
||||
}
|
||||
data := nestedSearchData(result, "conversation")
|
||||
root := searchDataRoot(result)
|
||||
data := nestedSearchDataFromRoot(root, "conversation")
|
||||
return map[string]any{
|
||||
"id": firstMapValue(data, "display_id", "id"),
|
||||
"account_id": firstMapValue(data, "account_id"),
|
||||
"created_at": unixFromMapValue(firstMapValue(data, "created_at", "created_at_ts")),
|
||||
"additional_attributes": firstMapValue(data, "additional_attributes"),
|
||||
"message": serializeSearchConversationMessageMap(firstNestedSearchData(root, data, "message")),
|
||||
"contact": serializeSearchConversationContactMap(firstNestedSearchData(root, data, "contact")),
|
||||
"inbox": serializeSearchConversationInboxMap(firstNestedSearchData(root, data, "inbox")),
|
||||
"agent": serializeSearchConversationAgentMap(firstNestedSearchData(root, data, "agent", "assignee")),
|
||||
}
|
||||
}
|
||||
|
||||
func serializeSearchConversationModel(conv *model.Conversation) map[string]any {
|
||||
return map[string]any{
|
||||
"id": conversationDisplayID(conv),
|
||||
"account_id": conv.AccountID,
|
||||
"created_at": conv.CreatedAt.Unix(),
|
||||
"additional_attributes": jsonObject(conv.AdditionalAttributes),
|
||||
"message": serializeSearchConversationMessageModel(conv),
|
||||
"contact": serializeSearchConversationContactModel(conv),
|
||||
"inbox": serializeSearchConversationInboxModel(conv),
|
||||
"agent": serializeSearchConversationAgentModel(conv),
|
||||
}
|
||||
}
|
||||
|
||||
func serializeSearchConversationMessageModel(conv *model.Conversation) map[string]any {
|
||||
if len(conv.Messages) == 0 {
|
||||
return map[string]any{}
|
||||
}
|
||||
return serializeSearchMessageModel(&conv.Messages[0])
|
||||
}
|
||||
|
||||
func serializeSearchConversationContactModel(conv *model.Conversation) map[string]any {
|
||||
if conv.Contact != nil {
|
||||
return serializeSearchContactModel(conv.Contact)
|
||||
}
|
||||
if conv.ContactID != 0 {
|
||||
return map[string]any{"id": conv.ContactID}
|
||||
}
|
||||
return map[string]any{}
|
||||
}
|
||||
|
||||
func serializeSearchConversationInboxModel(conv *model.Conversation) map[string]any {
|
||||
if conv.Inbox != nil {
|
||||
return map[string]any{
|
||||
"id": conv.Inbox.ID,
|
||||
"channel_id": conv.Inbox.ChannelID,
|
||||
"name": conv.Inbox.Name,
|
||||
"channel_type": conv.Inbox.ChannelType,
|
||||
}
|
||||
}
|
||||
if conv.InboxID != 0 {
|
||||
return map[string]any{"id": conv.InboxID, "channel_type": conv.ChannelType}
|
||||
}
|
||||
return map[string]any{}
|
||||
}
|
||||
|
||||
func serializeSearchConversationAgentModel(conv *model.Conversation) map[string]any {
|
||||
if conv.Assignee != nil {
|
||||
return map[string]any{
|
||||
"id": conv.Assignee.ID,
|
||||
"available_name": nonEmpty(conv.Assignee.DisplayName, conv.Assignee.Name),
|
||||
"email": conv.Assignee.Email,
|
||||
"name": conv.Assignee.Name,
|
||||
"role": nonEmpty(conv.Assignee.Role, "agent"),
|
||||
}
|
||||
}
|
||||
return map[string]any{}
|
||||
}
|
||||
|
||||
func serializeSearchConversationMessageMap(data map[string]any) map[string]any {
|
||||
if len(data) == 0 {
|
||||
return map[string]any{}
|
||||
}
|
||||
return serializeSearchMessage(search.SearchResult{Data: map[string]any{"message": data}})
|
||||
}
|
||||
|
||||
func serializeSearchConversationContactMap(data map[string]any) map[string]any {
|
||||
if len(data) == 0 {
|
||||
return map[string]any{}
|
||||
}
|
||||
return map[string]any{
|
||||
"email": firstMapValue(data, "email"),
|
||||
"id": firstMapValue(data, "id"),
|
||||
"name": firstMapValue(data, "name"),
|
||||
"phone_number": firstMapValue(data, "phone_number"),
|
||||
"identifier": firstMapValue(data, "identifier"),
|
||||
"additional_attributes": firstMapValue(data, "additional_attributes"),
|
||||
"last_activity_at": unixFromMapValue(firstMapValue(data, "last_activity_at")),
|
||||
}
|
||||
}
|
||||
|
||||
func serializeSearchConversationInboxMap(data map[string]any) map[string]any {
|
||||
if len(data) == 0 {
|
||||
return map[string]any{}
|
||||
}
|
||||
return map[string]any{
|
||||
"id": firstMapValue(data, "id"),
|
||||
"channel_id": firstMapValue(data, "channel_id"),
|
||||
"name": firstMapValue(data, "name"),
|
||||
"channel_type": firstMapValue(data, "channel_type"),
|
||||
}
|
||||
}
|
||||
|
||||
func serializeSearchConversationAgentMap(data map[string]any) map[string]any {
|
||||
if len(data) == 0 {
|
||||
return map[string]any{}
|
||||
}
|
||||
return map[string]any{
|
||||
"id": firstMapValue(data, "id"),
|
||||
"available_name": firstMapValue(data, "available_name", "display_name", "name"),
|
||||
"email": firstMapValue(data, "email"),
|
||||
"name": firstMapValue(data, "name"),
|
||||
"role": firstMapValue(data, "role"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -497,10 +597,21 @@ func serializeSearchArticleModel(article *model.Article) map[string]any {
|
||||
}
|
||||
|
||||
func nestedSearchData(result search.SearchResult, key string) map[string]any {
|
||||
return nestedSearchDataFromRoot(searchDataRoot(result), key)
|
||||
}
|
||||
|
||||
func searchDataRoot(result search.SearchResult) map[string]any {
|
||||
root, ok := anyMap(result.Data)
|
||||
if !ok {
|
||||
return map[string]any{}
|
||||
}
|
||||
if data, ok := anyMap(root["data"]); ok {
|
||||
return data
|
||||
}
|
||||
return root
|
||||
}
|
||||
|
||||
func nestedSearchDataFromRoot(root map[string]any, key string) map[string]any {
|
||||
if nested, ok := anyMap(root[key]); ok {
|
||||
return nested
|
||||
}
|
||||
@@ -513,6 +624,18 @@ func nestedSearchData(result search.SearchResult, key string) map[string]any {
|
||||
return root
|
||||
}
|
||||
|
||||
func firstNestedSearchData(root map[string]any, fallback map[string]any, keys ...string) map[string]any {
|
||||
for _, key := range keys {
|
||||
if nested, ok := anyMap(root[key]); ok {
|
||||
return nested
|
||||
}
|
||||
if nested, ok := anyMap(fallback[key]); ok {
|
||||
return nested
|
||||
}
|
||||
}
|
||||
return map[string]any{}
|
||||
}
|
||||
|
||||
func anyMap(value any) (map[string]any, bool) {
|
||||
switch typed := value.(type) {
|
||||
case map[string]any:
|
||||
|
||||
Reference in New Issue
Block a user