mirror of
				https://github.com/abhinavxd/libredesk.git
				synced 2025-11-04 05:53:30 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			191 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			191 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package main
 | 
						|
 | 
						|
import (
 | 
						|
	"strconv"
 | 
						|
 | 
						|
	amodels "github.com/abhinavxd/libredesk/internal/auth/models"
 | 
						|
	cmodels "github.com/abhinavxd/libredesk/internal/conversation/models"
 | 
						|
	"github.com/abhinavxd/libredesk/internal/envelope"
 | 
						|
	medModels "github.com/abhinavxd/libredesk/internal/media/models"
 | 
						|
	"github.com/valyala/fasthttp"
 | 
						|
	"github.com/zerodha/fastglue"
 | 
						|
)
 | 
						|
 | 
						|
type messageReq struct {
 | 
						|
	Attachments []int    `json:"attachments"`
 | 
						|
	Message     string   `json:"message"`
 | 
						|
	Private     bool     `json:"private"`
 | 
						|
	To          []string `json:"to"`
 | 
						|
	CC          []string `json:"cc"`
 | 
						|
	BCC         []string `json:"bcc"`
 | 
						|
}
 | 
						|
 | 
						|
// handleGetMessages returns messages for a conversation.
 | 
						|
func handleGetMessages(r *fastglue.Request) error {
 | 
						|
	var (
 | 
						|
		app         = r.Context.(*App)
 | 
						|
		uuid        = r.RequestCtx.UserValue("uuid").(string)
 | 
						|
		auser       = r.RequestCtx.UserValue("user").(amodels.User)
 | 
						|
		page, _     = strconv.Atoi(string(r.RequestCtx.QueryArgs().Peek("page")))
 | 
						|
		pageSize, _ = strconv.Atoi(string(r.RequestCtx.QueryArgs().Peek("page_size")))
 | 
						|
		total       = 0
 | 
						|
	)
 | 
						|
 | 
						|
	user, err := app.user.GetAgent(auser.ID, "")
 | 
						|
	if err != nil {
 | 
						|
		return sendErrorEnvelope(r, err)
 | 
						|
	}
 | 
						|
 | 
						|
	// Check permission
 | 
						|
	_, err = enforceConversationAccess(app, uuid, user)
 | 
						|
	if err != nil {
 | 
						|
		return sendErrorEnvelope(r, err)
 | 
						|
	}
 | 
						|
 | 
						|
	messages, pageSize, err := app.conversation.GetConversationMessages(uuid, []string{cmodels.MessageIncoming, cmodels.MessageOutgoing, cmodels.MessageActivity}, nil, page, pageSize)
 | 
						|
	if err != nil {
 | 
						|
		return sendErrorEnvelope(r, err)
 | 
						|
	}
 | 
						|
 | 
						|
	for i := range messages {
 | 
						|
		total = messages[i].Total
 | 
						|
		// Populate attachment URLs
 | 
						|
		for j := range messages[i].Attachments {
 | 
						|
			messages[i].Attachments[j].URL = app.media.GetURL(messages[i].Attachments[j].UUID)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	// Process CSAT status for all messages (will only affect CSAT messages)
 | 
						|
	app.conversation.ProcessCSATStatus(messages)
 | 
						|
 | 
						|
	return r.SendEnvelope(envelope.PageResults{
 | 
						|
		Total:      total,
 | 
						|
		Results:    messages,
 | 
						|
		Page:       page,
 | 
						|
		PerPage:    pageSize,
 | 
						|
		TotalPages: (total + pageSize - 1) / pageSize,
 | 
						|
	})
 | 
						|
}
 | 
						|
 | 
						|
// handleGetMessage fetches a single from DB using the uuid.
 | 
						|
func handleGetMessage(r *fastglue.Request) error {
 | 
						|
	var (
 | 
						|
		app   = r.Context.(*App)
 | 
						|
		uuid  = r.RequestCtx.UserValue("uuid").(string)
 | 
						|
		cuuid = r.RequestCtx.UserValue("cuuid").(string)
 | 
						|
		auser = r.RequestCtx.UserValue("user").(amodels.User)
 | 
						|
	)
 | 
						|
	user, err := app.user.GetAgent(auser.ID, "")
 | 
						|
	if err != nil {
 | 
						|
		return sendErrorEnvelope(r, err)
 | 
						|
	}
 | 
						|
 | 
						|
	// Check permission
 | 
						|
	_, err = enforceConversationAccess(app, cuuid, user)
 | 
						|
	if err != nil {
 | 
						|
		return sendErrorEnvelope(r, err)
 | 
						|
	}
 | 
						|
 | 
						|
	message, err := app.conversation.GetMessage(uuid)
 | 
						|
	if err != nil {
 | 
						|
		return sendErrorEnvelope(r, err)
 | 
						|
	}
 | 
						|
 | 
						|
	// Process CSAT status for the message (will only affect CSAT messages)
 | 
						|
	messages := []cmodels.Message{message}
 | 
						|
	app.conversation.ProcessCSATStatus(messages)
 | 
						|
	message = messages[0]
 | 
						|
 | 
						|
	for j := range message.Attachments {
 | 
						|
		message.Attachments[j].URL = app.media.GetURL(message.Attachments[j].UUID)
 | 
						|
	}
 | 
						|
 | 
						|
	return r.SendEnvelope(message)
 | 
						|
}
 | 
						|
 | 
						|
// handleRetryMessage changes message status so it can be retried for sending.
 | 
						|
func handleRetryMessage(r *fastglue.Request) error {
 | 
						|
	var (
 | 
						|
		app   = r.Context.(*App)
 | 
						|
		uuid  = r.RequestCtx.UserValue("uuid").(string)
 | 
						|
		cuuid = r.RequestCtx.UserValue("cuuid").(string)
 | 
						|
		auser = r.RequestCtx.UserValue("user").(amodels.User)
 | 
						|
	)
 | 
						|
 | 
						|
	user, err := app.user.GetAgent(auser.ID, "")
 | 
						|
	if err != nil {
 | 
						|
		return sendErrorEnvelope(r, err)
 | 
						|
	}
 | 
						|
 | 
						|
	// Check permission
 | 
						|
	_, err = enforceConversationAccess(app, cuuid, user)
 | 
						|
	if err != nil {
 | 
						|
		return sendErrorEnvelope(r, err)
 | 
						|
	}
 | 
						|
 | 
						|
	if err = app.conversation.MarkMessageAsPending(uuid); err != nil {
 | 
						|
		return sendErrorEnvelope(r, err)
 | 
						|
	}
 | 
						|
	return r.SendEnvelope(true)
 | 
						|
}
 | 
						|
 | 
						|
// handleSendMessage sends a message in a conversation.
 | 
						|
func handleSendMessage(r *fastglue.Request) error {
 | 
						|
	var (
 | 
						|
		app   = r.Context.(*App)
 | 
						|
		auser = r.RequestCtx.UserValue("user").(amodels.User)
 | 
						|
		cuuid = r.RequestCtx.UserValue("cuuid").(string)
 | 
						|
		req   = messageReq{}
 | 
						|
	)
 | 
						|
 | 
						|
	user, err := app.user.GetAgent(auser.ID, "")
 | 
						|
	if err != nil {
 | 
						|
		return sendErrorEnvelope(r, err)
 | 
						|
	}
 | 
						|
 | 
						|
	// Check access to conversation.
 | 
						|
	conv, err := enforceConversationAccess(app, cuuid, user)
 | 
						|
	if err != nil {
 | 
						|
		return sendErrorEnvelope(r, err)
 | 
						|
	}
 | 
						|
 | 
						|
	if err := r.Decode(&req, "json"); err != nil {
 | 
						|
		app.lo.Error("error unmarshalling message request", "error", err)
 | 
						|
		return r.SendErrorEnvelope(fasthttp.StatusInternalServerError, app.i18n.Ts("globals.messages.errorParsing", "name", "{globals.terms.request}"), nil, envelope.InputError)
 | 
						|
	}
 | 
						|
 | 
						|
	// Make sure the inbox is enabled.
 | 
						|
	inbox, err := app.inbox.GetDBRecord(conv.InboxID)
 | 
						|
	if err != nil {
 | 
						|
		return sendErrorEnvelope(r, err)
 | 
						|
	}
 | 
						|
	if !inbox.Enabled {
 | 
						|
		return r.SendErrorEnvelope(fasthttp.StatusBadRequest, app.i18n.Ts("globals.messages.disabled", "name", "{globals.terms.inbox}"), nil, envelope.InputError)
 | 
						|
	}
 | 
						|
 | 
						|
	// Prepare attachments.
 | 
						|
	var media = make([]medModels.Media, 0, len(req.Attachments))
 | 
						|
	for _, id := range req.Attachments {
 | 
						|
		m, err := app.media.Get(id, "")
 | 
						|
		if err != nil {
 | 
						|
			app.lo.Error("error fetching media", "error", err)
 | 
						|
			return r.SendErrorEnvelope(fasthttp.StatusInternalServerError, app.i18n.Ts("globals.messages.errorFetching", "name", "{globals.terms.media}"), nil, envelope.GeneralError)
 | 
						|
		}
 | 
						|
		media = append(media, m)
 | 
						|
	}
 | 
						|
 | 
						|
	if req.Private {
 | 
						|
		message, err := app.conversation.SendPrivateNote(media, user.ID, cuuid, req.Message)
 | 
						|
		if err != nil {
 | 
						|
			return sendErrorEnvelope(r, err)
 | 
						|
		}
 | 
						|
		return r.SendEnvelope(message)
 | 
						|
	}
 | 
						|
 | 
						|
	message, err := app.conversation.SendReply(media, conv.InboxID, user.ID, conv.ContactID, cuuid, req.Message, req.To, req.CC, req.BCC, map[string]any{} /**meta**/)
 | 
						|
	if err != nil {
 | 
						|
		return sendErrorEnvelope(r, err)
 | 
						|
	}
 | 
						|
	return r.SendEnvelope(message)
 | 
						|
}
 |