feat(widget): support chatwoot direct upload attachments
This commit is contained in:
@@ -113,8 +113,11 @@ func (h *WidgetHandler) Config(c *gin.Context) {
|
||||
"welcome_tagline": resp.WidgetConfig.WelcomeTagline,
|
||||
"website_name": resp.InboxName,
|
||||
},
|
||||
"contact": contact,
|
||||
"global_config": gin.H{},
|
||||
"contact": contact,
|
||||
"global_config": gin.H{
|
||||
"directUploadsEnabled": true,
|
||||
"maximumFileUploadSize": 40,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -149,7 +152,11 @@ func (h *WidgetHandler) SendMessage(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, resp)
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, widgetMessagePayload(resp.Message, resp.ConversationID))
|
||||
payload := widgetMessagePayload(resp.Message, resp.ConversationID)
|
||||
if len(resp.Attachments) > 0 {
|
||||
payload["attachments"] = widgetAttachmentPayloads(resp.Attachments)
|
||||
}
|
||||
c.JSON(http.StatusOK, payload)
|
||||
}
|
||||
|
||||
func (h *WidgetHandler) UpdateMessage(c *gin.Context) {
|
||||
@@ -216,7 +223,11 @@ func (h *WidgetHandler) GetLatestMessages(c *gin.Context) {
|
||||
|
||||
payload := make([]gin.H, 0, len(messages))
|
||||
for _, msg := range messages {
|
||||
payload = append(payload, widgetMessagePayload(msg, msg.ConversationID))
|
||||
messagePayload := widgetMessagePayload(msg, msg.ConversationID)
|
||||
if attachments, err := h.widgetService.GetMessageAttachments(c.Request.Context(), msg.ID); err == nil && len(attachments) > 0 {
|
||||
messagePayload["attachments"] = widgetAttachmentPayloads(attachments)
|
||||
}
|
||||
payload = append(payload, messagePayload)
|
||||
}
|
||||
meta := gin.H{"total": total, "offset": offset, "limit": limit}
|
||||
if conversation != nil && conversation.ContactLastSeenAt != nil {
|
||||
@@ -988,12 +999,40 @@ func widgetTokenFromRequest(c *gin.Context) string {
|
||||
}
|
||||
|
||||
func bindWidgetSendMessageRequest(c *gin.Context) (service.WidgetSendMessageRequest, error) {
|
||||
if strings.Contains(c.GetHeader("Content-Type"), "multipart/form-data") {
|
||||
if err := c.Request.ParseMultipartForm(32 << 20); err != nil {
|
||||
return service.WidgetSendMessageRequest{}, err
|
||||
}
|
||||
form := c.Request.MultipartForm
|
||||
content := firstFormValue(form.Value, "content", "message[content]")
|
||||
contentType := firstFormValue(form.Value, "content_type", "message[content_type]")
|
||||
var conversationID *uint
|
||||
if rawID := firstFormValue(form.Value, "conversation_id", "message[conversation_id]"); rawID != "" {
|
||||
if id, err := strconv.ParseUint(rawID, 10, 64); err == nil && id > 0 {
|
||||
value := uint(id)
|
||||
conversationID = &value
|
||||
}
|
||||
}
|
||||
attachments := form.Value["message[attachments][]"]
|
||||
if len(attachments) == 0 {
|
||||
attachments = form.Value["attachments[]"]
|
||||
}
|
||||
return service.WidgetSendMessageRequest{
|
||||
Content: content,
|
||||
ContentType: contentType,
|
||||
ConversationID: conversationID,
|
||||
AttachmentIDs: attachments,
|
||||
}, nil
|
||||
}
|
||||
|
||||
var body struct {
|
||||
Content string `json:"content"`
|
||||
ContentType string `json:"content_type"`
|
||||
ConversationID *uint `json:"conversation_id"`
|
||||
Content string `json:"content"`
|
||||
ContentType string `json:"content_type"`
|
||||
ConversationID *uint `json:"conversation_id"`
|
||||
Attachments []string `json:"attachments"`
|
||||
Message struct {
|
||||
Content string `json:"content"`
|
||||
Content string `json:"content"`
|
||||
Attachments []string `json:"attachments"`
|
||||
} `json:"message"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&body); err != nil {
|
||||
@@ -1003,13 +1042,27 @@ func bindWidgetSendMessageRequest(c *gin.Context) (service.WidgetSendMessageRequ
|
||||
if content == "" {
|
||||
content = body.Message.Content
|
||||
}
|
||||
attachments := body.Attachments
|
||||
if len(attachments) == 0 {
|
||||
attachments = body.Message.Attachments
|
||||
}
|
||||
return service.WidgetSendMessageRequest{
|
||||
Content: content,
|
||||
ContentType: body.ContentType,
|
||||
ConversationID: body.ConversationID,
|
||||
AttachmentIDs: attachments,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func firstFormValue(values map[string][]string, keys ...string) string {
|
||||
for _, key := range keys {
|
||||
if list := values[key]; len(list) > 0 {
|
||||
return list[0]
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func widgetMessagePayload(message model.Message, conversationID uint) gin.H {
|
||||
return gin.H{
|
||||
"id": message.ID,
|
||||
@@ -1025,6 +1078,33 @@ func widgetMessagePayload(message model.Message, conversationID uint) gin.H {
|
||||
}
|
||||
}
|
||||
|
||||
func widgetAttachmentPayloads(attachments []model.Attachment) []gin.H {
|
||||
payload := make([]gin.H, 0, len(attachments))
|
||||
for _, attachment := range attachments {
|
||||
payload = append(payload, gin.H{
|
||||
"id": attachment.ID,
|
||||
"message_id": attachment.MessageID,
|
||||
"thumb_url": attachment.ThumbURL,
|
||||
"data_url": attachment.FileURL,
|
||||
"file_size": attachment.FileSize,
|
||||
"file_type": attachment.FileType,
|
||||
"extension": strings.TrimPrefix(strings.ToLower(attachmentExtension(attachment.FileName)), "."),
|
||||
"width": attachment.Width,
|
||||
"height": attachment.Height,
|
||||
"created_at": attachment.CreatedAt.Unix(),
|
||||
})
|
||||
}
|
||||
return payload
|
||||
}
|
||||
|
||||
func attachmentExtension(filename string) string {
|
||||
idx := strings.LastIndex(filename, ".")
|
||||
if idx == -1 {
|
||||
return ""
|
||||
}
|
||||
return filename[idx:]
|
||||
}
|
||||
|
||||
func widgetConversationPayload(conversation model.Conversation) gin.H {
|
||||
return gin.H{
|
||||
"id": conversation.ID,
|
||||
|
||||
Reference in New Issue
Block a user