mirror of
https://github.com/abhinavxd/libredesk.git
synced 2025-10-23 16:14:12 +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)
|
|
}
|