@@ -3,21 +3,33 @@ package main
3
3
import (
4
4
"encoding/json"
5
5
"strconv"
6
- "strings"
7
6
"time"
8
7
9
8
amodels "github.com/abhinavxd/libredesk/internal/auth/models"
10
9
authzModels "github.com/abhinavxd/libredesk/internal/authz/models"
11
10
"github.com/abhinavxd/libredesk/internal/automation/models"
12
11
cmodels "github.com/abhinavxd/libredesk/internal/conversation/models"
13
12
"github.com/abhinavxd/libredesk/internal/envelope"
13
+ medModels "github.com/abhinavxd/libredesk/internal/media/models"
14
14
"github.com/abhinavxd/libredesk/internal/stringutil"
15
15
umodels "github.com/abhinavxd/libredesk/internal/user/models"
16
16
"github.com/valyala/fasthttp"
17
17
"github.com/volatiletech/null/v9"
18
18
"github.com/zerodha/fastglue"
19
19
)
20
20
21
+ type createConversationRequest struct {
22
+ InboxID int `json:"inbox_id" form:"inbox_id"`
23
+ AssignedAgentID int `json:"agent_id" form:"agent_id"`
24
+ AssignedTeamID int `json:"team_id" form:"team_id"`
25
+ Email string `json:"contact_email" form:"contact_email"`
26
+ FirstName string `json:"first_name" form:"first_name"`
27
+ LastName string `json:"last_name" form:"last_name"`
28
+ Subject string `json:"subject" form:"subject"`
29
+ Content string `json:"content" form:"content"`
30
+ Attachments []int `json:"attachments" form:"attachments"`
31
+ }
32
+
21
33
// handleGetAllConversations retrieves all conversations.
22
34
func handleGetAllConversations (r * fastglue.Request ) error {
23
35
var (
@@ -632,36 +644,32 @@ func filterCurrentConv(convs []cmodels.Conversation, uuid string) []cmodels.Conv
632
644
// handleCreateConversation creates a new conversation and sends a message to it.
633
645
func handleCreateConversation (r * fastglue.Request ) error {
634
646
var (
635
- app = r .Context .(* App )
636
- auser = r .RequestCtx .UserValue ("user" ).(amodels.User )
637
- inboxID = r .RequestCtx .PostArgs ().GetUintOrZero ("inbox_id" )
638
- assignedAgentID = r .RequestCtx .PostArgs ().GetUintOrZero ("agent_id" )
639
- assignedTeamID = r .RequestCtx .PostArgs ().GetUintOrZero ("team_id" )
640
- email = strings .TrimSpace (string (r .RequestCtx .PostArgs ().Peek ("contact_email" )))
641
- firstName = strings .TrimSpace (string (r .RequestCtx .PostArgs ().Peek ("first_name" )))
642
- lastName = strings .TrimSpace (string (r .RequestCtx .PostArgs ().Peek ("last_name" )))
643
- subject = strings .TrimSpace (string (r .RequestCtx .PostArgs ().Peek ("subject" )))
644
- content = strings .TrimSpace (string (r .RequestCtx .PostArgs ().Peek ("content" )))
645
- to = []string {email }
647
+ app = r .Context .(* App )
648
+ auser = r .RequestCtx .UserValue ("user" ).(amodels.User )
649
+ req = createConversationRequest {}
646
650
)
647
651
648
- // Validate required fields
649
- if inboxID <= 0 {
650
- return r .SendErrorEnvelope (fasthttp .StatusBadRequest , app .i18n .Ts ("globals.messages.fieldRequired " , "name" , "`inbox_id` " ), nil , envelope .InputError )
652
+ if err := r . Decode ( & req , "json" ); err != nil {
653
+ app . lo . Error ( "error decoding create conversation request" , "error" , err )
654
+ return r .SendErrorEnvelope (fasthttp .StatusBadRequest , app .i18n .Ts ("globals.messages.errorParsing " , "name" , "{globals.terms.request} " ), nil , envelope .InputError )
651
655
}
652
- if subject == "" {
653
- return r .SendErrorEnvelope (fasthttp .StatusBadRequest , app .i18n .Ts ("globals.messages.fieldRequired" , "name" , "`subject`" ), nil , envelope .InputError )
656
+
657
+ to := []string {req .Email }
658
+
659
+ // Validate required fields
660
+ if req .InboxID <= 0 {
661
+ return r .SendErrorEnvelope (fasthttp .StatusBadRequest , app .i18n .Ts ("globals.messages.required" , "name" , "`inbox_id`" ), nil , envelope .InputError )
654
662
}
655
- if content == "" {
656
- return r .SendErrorEnvelope (fasthttp .StatusBadRequest , app .i18n .Ts ("globals.messages.fieldRequired " , "name" , "`content`" ), nil , envelope .InputError )
663
+ if req . Content == "" {
664
+ return r .SendErrorEnvelope (fasthttp .StatusBadRequest , app .i18n .Ts ("globals.messages.required " , "name" , "`content`" ), nil , envelope .InputError )
657
665
}
658
- if email == "" {
659
- return r .SendErrorEnvelope (fasthttp .StatusBadRequest , app .i18n .Ts ("globals.messages.fieldRequired " , "name" , "`contact_email`" ), nil , envelope .InputError )
666
+ if req . Email == "" {
667
+ return r .SendErrorEnvelope (fasthttp .StatusBadRequest , app .i18n .Ts ("globals.messages.required " , "name" , "`contact_email`" ), nil , envelope .InputError )
660
668
}
661
- if firstName == "" {
662
- return r .SendErrorEnvelope (fasthttp .StatusBadRequest , app .i18n .Ts ("globals.messages.fieldRequired " , "name" , "`first_name`" ), nil , envelope .InputError )
669
+ if req . FirstName == "" {
670
+ return r .SendErrorEnvelope (fasthttp .StatusBadRequest , app .i18n .Ts ("globals.messages.required " , "name" , "`first_name`" ), nil , envelope .InputError )
663
671
}
664
- if ! stringutil .ValidEmail (email ) {
672
+ if ! stringutil .ValidEmail (req . Email ) {
665
673
return r .SendErrorEnvelope (fasthttp .StatusBadRequest , app .i18n .Ts ("globals.messages.invalid" , "name" , "`contact_email`" ), nil , envelope .InputError )
666
674
}
667
675
@@ -671,7 +679,7 @@ func handleCreateConversation(r *fastglue.Request) error {
671
679
}
672
680
673
681
// Check if inbox exists and is enabled.
674
- inbox , err := app .inbox .GetDBRecord (inboxID )
682
+ inbox , err := app .inbox .GetDBRecord (req . InboxID )
675
683
if err != nil {
676
684
return sendErrorEnvelope (r , err )
677
685
}
@@ -681,11 +689,11 @@ func handleCreateConversation(r *fastglue.Request) error {
681
689
682
690
// Find or create contact.
683
691
contact := umodels.User {
684
- Email : null .StringFrom (email ),
685
- SourceChannelID : null .StringFrom (email ),
686
- FirstName : firstName ,
687
- LastName : lastName ,
688
- InboxID : inboxID ,
692
+ Email : null .StringFrom (req . Email ),
693
+ SourceChannelID : null .StringFrom (req . Email ),
694
+ FirstName : req . FirstName ,
695
+ LastName : req . LastName ,
696
+ InboxID : req . InboxID ,
689
697
}
690
698
if err := app .user .CreateContact (& contact ); err != nil {
691
699
return sendErrorEnvelope (r , envelope .NewError (envelope .GeneralError , app .i18n .Ts ("globals.messages.errorCreating" , "name" , "{globals.terms.contact}" ), nil ))
@@ -695,19 +703,30 @@ func handleCreateConversation(r *fastglue.Request) error {
695
703
conversationID , conversationUUID , err := app .conversation .CreateConversation (
696
704
contact .ID ,
697
705
contact .ContactChannelID ,
698
- inboxID ,
706
+ req . InboxID ,
699
707
"" , /** last_message **/
700
708
time .Now (), /** last_message_at **/
701
- subject ,
709
+ req . Subject ,
702
710
true , /** append reference number to subject **/
703
711
)
704
712
if err != nil {
705
713
app .lo .Error ("error creating conversation" , "error" , err )
706
714
return sendErrorEnvelope (r , envelope .NewError (envelope .GeneralError , app .i18n .Ts ("globals.messages.errorCreating" , "name" , "{globals.terms.conversation}" ), nil ))
707
715
}
708
716
717
+ // Prepare attachments.
718
+ var media = make ([]medModels.Media , 0 , len (req .Attachments ))
719
+ for _ , id := range req .Attachments {
720
+ m , err := app .media .Get (id , "" )
721
+ if err != nil {
722
+ app .lo .Error ("error fetching media" , "error" , err )
723
+ return r .SendErrorEnvelope (fasthttp .StatusInternalServerError , app .i18n .Ts ("globals.messages.errorFetching" , "name" , "{globals.terms.media}" ), nil , envelope .GeneralError )
724
+ }
725
+ media = append (media , m )
726
+ }
727
+
709
728
// Send reply to the created conversation.
710
- if err := app .conversation .SendReply (nil /** media**/ , inboxID , auser .ID /**sender_id**/ , conversationUUID , content , to , nil /**cc**/ , nil /**bcc**/ , map [string ]any {} /**meta**/ ); err != nil {
729
+ if err := app .conversation .SendReply (media , req . InboxID , auser .ID /**sender_id**/ , conversationUUID , req . Content , to , nil /**cc**/ , nil /**bcc**/ , map [string ]any {} /**meta**/ ); err != nil {
711
730
// Delete the conversation if reply fails.
712
731
if err := app .conversation .DeleteConversation (conversationUUID ); err != nil {
713
732
app .lo .Error ("error deleting conversation" , "error" , err )
@@ -716,11 +735,11 @@ func handleCreateConversation(r *fastglue.Request) error {
716
735
}
717
736
718
737
// Assign the conversation to the agent or team.
719
- if assignedAgentID > 0 {
720
- app .conversation .UpdateConversationUserAssignee (conversationUUID , assignedAgentID , user )
738
+ if req . AssignedAgentID > 0 {
739
+ app .conversation .UpdateConversationUserAssignee (conversationUUID , req . AssignedAgentID , user )
721
740
}
722
- if assignedTeamID > 0 {
723
- app .conversation .UpdateConversationTeamAssignee (conversationUUID , assignedTeamID , user )
741
+ if req . AssignedTeamID > 0 {
742
+ app .conversation .UpdateConversationTeamAssignee (conversationUUID , req . AssignedTeamID , user )
724
743
}
725
744
726
745
// Send the created conversation back to the client.
0 commit comments