229 lines
7.5 KiB
Go
229 lines
7.5 KiB
Go
package v1
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/gochat/gochat/internal/model"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type chatwootContactMeta struct {
|
|
Count int64 `json:"count"`
|
|
CurrentPage int `json:"current_page"`
|
|
HasMore *bool `json:"has_more,omitempty"`
|
|
}
|
|
|
|
type chatwootCompanyMeta struct {
|
|
TotalCount int64 `json:"total_count"`
|
|
Page int `json:"page"`
|
|
}
|
|
|
|
func contactListResponse(ctx context.Context, db *gorm.DB, contacts []model.Contact, total int64, page int, includeInboxes bool, hasMore *bool) map[string]any {
|
|
payload := make([]any, 0, len(contacts))
|
|
for i := range contacts {
|
|
payload = append(payload, serializeCRMContact(ctx, db, &contacts[i], includeInboxes))
|
|
}
|
|
return map[string]any{
|
|
"meta": chatwootContactMeta{Count: total, CurrentPage: page, HasMore: hasMore},
|
|
"payload": payload,
|
|
}
|
|
}
|
|
|
|
func contactPayloadResponse(ctx context.Context, db *gorm.DB, contact *model.Contact, includeInboxes bool) map[string]any {
|
|
payload := serializeCRMContact(ctx, db, contact, includeInboxes)
|
|
return map[string]any{"payload": payload}
|
|
}
|
|
|
|
func contactCreateResponse(ctx context.Context, db *gorm.DB, contact *model.Contact, contactInbox *model.ContactInbox) map[string]any {
|
|
payload := map[string]any{
|
|
"contact": serializeCRMContact(ctx, db, contact, true),
|
|
"contact_inbox": serializeContactInboxShell(contactInbox),
|
|
}
|
|
return map[string]any{"payload": payload}
|
|
}
|
|
|
|
func serializeCRMContact(ctx context.Context, db *gorm.DB, contact *model.Contact, includeInboxes bool) map[string]any {
|
|
payload := map[string]any{
|
|
"additional_attributes": jsonObject(contact.AdditionalAttributes),
|
|
"availability_status": "offline",
|
|
"email": contact.Email,
|
|
"id": contact.ID,
|
|
"name": contact.Name,
|
|
"phone_number": contact.PhoneNumber,
|
|
"blocked": contact.Blocked,
|
|
"identifier": contact.Identifier,
|
|
"thumbnail": contact.AvatarURL,
|
|
"custom_attributes": jsonObject(contact.CustomAttributes),
|
|
}
|
|
if contact.LastActivityAt != nil {
|
|
payload["last_activity_at"] = *contact.LastActivityAt
|
|
}
|
|
if !contact.CreatedAt.IsZero() {
|
|
payload["created_at"] = contact.CreatedAt.Unix()
|
|
}
|
|
if includeInboxes {
|
|
payload["contact_inboxes"] = []any{}
|
|
if db != nil {
|
|
var contactInboxes []model.ContactInbox
|
|
if err := db.WithContext(ctx).Preload("Inbox").Where("contact_id = ?", contact.ID).Order("id ASC").Find(&contactInboxes).Error; err == nil {
|
|
items := make([]any, 0, len(contactInboxes))
|
|
for i := range contactInboxes {
|
|
items = append(items, serializeContactInbox(&contactInboxes[i]))
|
|
}
|
|
payload["contact_inboxes"] = items
|
|
}
|
|
}
|
|
}
|
|
return payload
|
|
}
|
|
|
|
func serializeCompanyContact(ctx context.Context, db *gorm.DB, contact *model.Contact, currentCompanyID uint) map[string]any {
|
|
payload := serializeCRMContact(ctx, db, contact, false)
|
|
payload["company_id"] = contact.CompanyID
|
|
payload["linked_to_current_company"] = contact.CompanyID != nil && *contact.CompanyID == currentCompanyID
|
|
payload["company"] = nil
|
|
if db != nil && contact.CompanyID != nil {
|
|
var company model.Company
|
|
if err := db.WithContext(ctx).First(&company, *contact.CompanyID).Error; err == nil {
|
|
payload["company"] = serializeCompany(ctx, db, &company)
|
|
}
|
|
}
|
|
return payload
|
|
}
|
|
|
|
func serializeContactInbox(contactInbox *model.ContactInbox) map[string]any {
|
|
return map[string]any{
|
|
"source_id": contactInbox.SourceID,
|
|
"inbox": serializeInboxSlim(&contactInbox.Inbox),
|
|
}
|
|
}
|
|
|
|
func serializeContactInboxShell(contactInbox *model.ContactInbox) map[string]any {
|
|
if contactInbox == nil {
|
|
return map[string]any{"inbox": nil, "source_id": nil}
|
|
}
|
|
return map[string]any{"inbox": contactInbox.Inbox, "source_id": contactInbox.SourceID}
|
|
}
|
|
|
|
func serializeInboxSlim(inbox *model.Inbox) map[string]any {
|
|
if inbox == nil || inbox.ID == 0 {
|
|
return map[string]any{}
|
|
}
|
|
return map[string]any{
|
|
"id": inbox.ID,
|
|
"name": inbox.Name,
|
|
"channel_type": inbox.ChannelType,
|
|
"account_id": inbox.AccountID,
|
|
}
|
|
}
|
|
|
|
func companyListResponse(ctx context.Context, db *gorm.DB, companies []model.Company, total int64, page int) map[string]any {
|
|
payload := make([]any, 0, len(companies))
|
|
for i := range companies {
|
|
payload = append(payload, serializeCompany(ctx, db, &companies[i]))
|
|
}
|
|
return map[string]any{
|
|
"meta": chatwootCompanyMeta{TotalCount: total, Page: page},
|
|
"payload": payload,
|
|
}
|
|
}
|
|
|
|
func companyPayloadResponse(ctx context.Context, db *gorm.DB, company *model.Company) map[string]any {
|
|
payload := serializeCompany(ctx, db, company)
|
|
return map[string]any{"payload": payload}
|
|
}
|
|
|
|
func serializeCompany(ctx context.Context, db *gorm.DB, company *model.Company) map[string]any {
|
|
return map[string]any{
|
|
"id": company.ID,
|
|
"name": company.Name,
|
|
"contacts_count": companyContactsCount(ctx, db, company),
|
|
"domain": company.Domain,
|
|
"description": company.Description,
|
|
"custom_attributes": jsonObject(company.CustomAttributes),
|
|
"avatar_url": company.FaviconURL,
|
|
"last_activity_at": unixTimePtr(company.LastActivityAt),
|
|
"created_at": company.CreatedAt.Unix(),
|
|
"updated_at": company.UpdatedAt.Unix(),
|
|
}
|
|
}
|
|
|
|
func companyContactsResponse(ctx context.Context, db *gorm.DB, companyID uint, contacts []model.Contact, total int64, page int) map[string]any {
|
|
payload := make([]any, 0, len(contacts))
|
|
for i := range contacts {
|
|
payload = append(payload, serializeCompanyContact(ctx, db, &contacts[i], companyID))
|
|
}
|
|
return map[string]any{
|
|
"meta": chatwootCompanyMeta{TotalCount: total, Page: page},
|
|
"payload": payload,
|
|
}
|
|
}
|
|
|
|
func companyNotesResponse(ctx context.Context, db *gorm.DB, notes []model.CompanyNote, accountID uint) map[string]any {
|
|
payload := make([]any, 0, len(notes))
|
|
for i := range notes {
|
|
payload = append(payload, serializeCompanyNote(ctx, db, ¬es[i], accountID))
|
|
}
|
|
return map[string]any{"payload": payload}
|
|
}
|
|
|
|
func contactNotesResponse(notes []model.Note) []any {
|
|
payload := make([]any, 0, len(notes))
|
|
for i := range notes {
|
|
payload = append(payload, serializeContactNote(¬es[i]))
|
|
}
|
|
return payload
|
|
}
|
|
|
|
func serializeContactNote(note *model.Note) map[string]any {
|
|
item := map[string]any{
|
|
"id": note.ID,
|
|
"content": note.Content,
|
|
"account_id": note.AccountID,
|
|
"contact_id": note.ContactID,
|
|
"created_at": note.CreatedAt.Unix(),
|
|
"updated_at": note.UpdatedAt.Unix(),
|
|
}
|
|
if note.UserID != nil {
|
|
item["user_id"] = *note.UserID
|
|
}
|
|
if note.User != nil && note.User.ID != 0 {
|
|
item["user"] = serializeUser(note.User, note.AccountID)
|
|
}
|
|
return item
|
|
}
|
|
|
|
func serializeCompanyNote(ctx context.Context, db *gorm.DB, note *model.CompanyNote, accountID uint) map[string]any {
|
|
item := map[string]any{
|
|
"id": note.ID,
|
|
"content": note.Content,
|
|
"company_id": note.CompanyID,
|
|
"user_id": note.UserID,
|
|
"created_at": note.CreatedAt.Unix(),
|
|
"updated_at": note.UpdatedAt.Unix(),
|
|
}
|
|
if note.User.ID != 0 {
|
|
item["user"] = serializeUser(¬e.User, accountID)
|
|
} else if db != nil && note.UserID != 0 {
|
|
item["user"] = serializeUserFromDB(ctx, db, note.UserID, accountID)
|
|
}
|
|
return item
|
|
}
|
|
|
|
func companyContactsCount(ctx context.Context, db *gorm.DB, company *model.Company) int64 {
|
|
if db == nil || company == nil || company.ID == 0 {
|
|
return 0
|
|
}
|
|
var count int64
|
|
_ = db.WithContext(ctx).Model(&model.Contact{}).Where("account_id = ? AND company_id = ?", company.AccountID, company.ID).Count(&count).Error
|
|
return count
|
|
}
|
|
|
|
func unixTimePtr(value *time.Time) any {
|
|
if value == nil {
|
|
return nil
|
|
}
|
|
return value.Unix()
|
|
}
|