feat(inboxes): bind chatwoot channel settings
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gochat/gochat/internal/service"
|
||||
@@ -116,7 +119,7 @@ func (h *InboxHandler) Create(c *gin.Context) {
|
||||
}
|
||||
|
||||
var req service.CreateInboxRequest
|
||||
if bindErr := c.ShouldBindJSON(&req); bindErr != nil {
|
||||
if bindErr := bindCreateInboxRequest(c, &req); bindErr != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": bindErr.Error()})
|
||||
return
|
||||
}
|
||||
@@ -162,7 +165,7 @@ func (h *InboxHandler) Update(c *gin.Context) {
|
||||
}
|
||||
|
||||
var req service.UpdateInboxRequest
|
||||
if bindErr := c.ShouldBindJSON(&req); bindErr != nil {
|
||||
if bindErr := bindUpdateInboxRequest(c, &req); bindErr != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": bindErr.Error()})
|
||||
return
|
||||
}
|
||||
@@ -214,6 +217,232 @@ func (h *InboxHandler) Delete(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{"message": "Your inbox deletion request will be processed in some time."})
|
||||
}
|
||||
|
||||
func bindCreateInboxRequest(c *gin.Context, req *service.CreateInboxRequest) error {
|
||||
if strings.Contains(c.ContentType(), "json") {
|
||||
return c.ShouldBindJSON(req)
|
||||
}
|
||||
values, err := inboxFormValues(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
applyCreateInboxForm(req, values)
|
||||
return nil
|
||||
}
|
||||
|
||||
func bindUpdateInboxRequest(c *gin.Context, req *service.UpdateInboxRequest) error {
|
||||
if strings.Contains(c.ContentType(), "json") {
|
||||
return c.ShouldBindJSON(req)
|
||||
}
|
||||
values, err := inboxFormValues(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
applyUpdateInboxForm(req, values)
|
||||
return nil
|
||||
}
|
||||
|
||||
func inboxFormValues(c *gin.Context) (map[string][]string, error) {
|
||||
values := map[string][]string{}
|
||||
if strings.Contains(c.ContentType(), "multipart/form-data") {
|
||||
if err := c.Request.ParseMultipartForm(32 << 20); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if c.Request.MultipartForm != nil {
|
||||
for key, list := range c.Request.MultipartForm.Value {
|
||||
values[key] = append(values[key], list...)
|
||||
}
|
||||
}
|
||||
return values, nil
|
||||
} else if err := c.Request.ParseForm(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for key, list := range c.Request.PostForm {
|
||||
values[key] = append(values[key], list...)
|
||||
}
|
||||
for key, list := range c.Request.Form {
|
||||
if _, ok := values[key]; !ok {
|
||||
values[key] = append(values[key], list...)
|
||||
}
|
||||
}
|
||||
return values, nil
|
||||
}
|
||||
|
||||
func applyCreateInboxForm(req *service.CreateInboxRequest, values map[string][]string) {
|
||||
req.Channel = map[string]any{}
|
||||
for key, list := range values {
|
||||
value := inboxFormValue(list)
|
||||
if strings.HasPrefix(key, "channel[") {
|
||||
applyInboxNestedValue(req.Channel, key, list)
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(key, "csat_config[") {
|
||||
if req.CsatConfig == nil {
|
||||
req.CsatConfig = map[string]any{}
|
||||
}
|
||||
applyInboxNestedValue(req.CsatConfig, key, list)
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
case "name":
|
||||
req.Name = value
|
||||
case "channel_type":
|
||||
req.ChannelType = value
|
||||
case "enabled":
|
||||
req.Enabled = inboxBool(value)
|
||||
case "enable_auto_assignment":
|
||||
req.EnableAutoAssignment = inboxBool(value)
|
||||
case "greeting_enabled":
|
||||
req.GreetingEnabled = inboxBoolPtr(value)
|
||||
case "greeting_message":
|
||||
req.GreetingMessage = inboxStringPtr(value)
|
||||
case "enable_email_collect":
|
||||
req.EnableEmailCollect = inboxBoolPtr(value)
|
||||
case "csat_survey_enabled":
|
||||
req.CsatSurveyEnabled = inboxBoolPtr(value)
|
||||
case "working_hours_enabled":
|
||||
req.WorkingHoursEnabled = inboxBoolPtr(value)
|
||||
case "out_of_office_message":
|
||||
req.OutOfOfficeMessage = inboxStringPtr(value)
|
||||
case "timezone":
|
||||
req.Timezone = inboxStringPtr(value)
|
||||
case "allow_messages_after_resolved":
|
||||
req.AllowMessagesAfterResolved = inboxBoolPtr(value)
|
||||
case "lock_to_single_conversation":
|
||||
req.LockToSingleConversation = inboxBoolPtr(value)
|
||||
case "portal_id":
|
||||
req.PortalID = inboxUintPtr(value)
|
||||
case "sender_name_type":
|
||||
req.SenderNameType = inboxStringPtr(value)
|
||||
case "business_name":
|
||||
req.BusinessName = inboxStringPtr(value)
|
||||
case "csat_config":
|
||||
req.CsatConfig = inboxJSONObject(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func applyUpdateInboxForm(req *service.UpdateInboxRequest, values map[string][]string) {
|
||||
req.Channel = map[string]any{}
|
||||
for key, list := range values {
|
||||
value := inboxFormValue(list)
|
||||
if strings.HasPrefix(key, "channel[") {
|
||||
applyInboxNestedValue(req.Channel, key, list)
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(key, "csat_config[") {
|
||||
if req.CsatConfig == nil {
|
||||
req.CsatConfig = map[string]any{}
|
||||
}
|
||||
applyInboxNestedValue(req.CsatConfig, key, list)
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
case "name":
|
||||
req.Name = value
|
||||
case "enabled":
|
||||
req.Enabled = inboxBoolPtr(value)
|
||||
case "enable_auto_assignment":
|
||||
req.EnableAutoAssignment = inboxBoolPtr(value)
|
||||
case "greeting_enabled":
|
||||
req.GreetingEnabled = inboxBoolPtr(value)
|
||||
case "greeting_message":
|
||||
req.GreetingMessage = inboxStringPtr(value)
|
||||
case "enable_email_collect":
|
||||
req.EnableEmailCollect = inboxBoolPtr(value)
|
||||
case "csat_survey_enabled":
|
||||
req.CsatSurveyEnabled = inboxBoolPtr(value)
|
||||
case "working_hours_enabled":
|
||||
req.WorkingHoursEnabled = inboxBoolPtr(value)
|
||||
case "out_of_office_message":
|
||||
req.OutOfOfficeMessage = inboxStringPtr(value)
|
||||
case "timezone":
|
||||
req.Timezone = inboxStringPtr(value)
|
||||
case "allow_messages_after_resolved":
|
||||
req.AllowMessagesAfterResolved = inboxBoolPtr(value)
|
||||
case "lock_to_single_conversation":
|
||||
req.LockToSingleConversation = inboxBoolPtr(value)
|
||||
case "portal_id":
|
||||
req.PortalID = inboxUintPtr(value)
|
||||
case "sender_name_type":
|
||||
req.SenderNameType = inboxStringPtr(value)
|
||||
case "business_name":
|
||||
req.BusinessName = inboxStringPtr(value)
|
||||
case "csat_config":
|
||||
req.CsatConfig = inboxJSONObject(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func applyInboxNestedValue(target map[string]any, key string, values []string) {
|
||||
inner := strings.TrimSuffix(strings.TrimPrefix(key[strings.Index(key, "[")+1:], ""), "]")
|
||||
parts := strings.Split(inner, "][")
|
||||
if len(parts) == 0 || parts[0] == "" {
|
||||
return
|
||||
}
|
||||
if len(parts) == 1 || (len(parts) == 2 && parts[1] == "") {
|
||||
if len(parts) == 2 && parts[1] == "" {
|
||||
target[parts[0]] = append([]string(nil), values...)
|
||||
return
|
||||
}
|
||||
target[parts[0]] = inboxFormValue(values)
|
||||
return
|
||||
}
|
||||
nested, _ := target[parts[0]].(map[string]any)
|
||||
if nested == nil {
|
||||
nested = map[string]any{}
|
||||
target[parts[0]] = nested
|
||||
}
|
||||
if len(parts) == 3 && parts[2] == "" {
|
||||
nested[parts[1]] = append([]string(nil), values...)
|
||||
return
|
||||
}
|
||||
nested[parts[1]] = inboxFormValue(values)
|
||||
}
|
||||
|
||||
func inboxFormValue(values []string) string {
|
||||
if len(values) == 0 || values[0] == "null" {
|
||||
return ""
|
||||
}
|
||||
return values[0]
|
||||
}
|
||||
|
||||
func inboxBool(value string) bool {
|
||||
parsed, _ := strconv.ParseBool(value)
|
||||
return parsed
|
||||
}
|
||||
|
||||
func inboxBoolPtr(value string) *bool {
|
||||
parsed := inboxBool(value)
|
||||
return &parsed
|
||||
}
|
||||
|
||||
func inboxStringPtr(value string) *string {
|
||||
return &value
|
||||
}
|
||||
|
||||
func inboxUintPtr(value string) *uint {
|
||||
if value == "" {
|
||||
return nil
|
||||
}
|
||||
parsed, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
uintValue := uint(parsed)
|
||||
return &uintValue
|
||||
}
|
||||
|
||||
func inboxJSONObject(value string) map[string]any {
|
||||
if value == "" {
|
||||
return nil
|
||||
}
|
||||
var data map[string]any
|
||||
if err := json.Unmarshal([]byte(value), &data); err != nil {
|
||||
return nil
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// Member-action handlers (Chatwoot InboxesController member routes)
|
||||
// ========================================
|
||||
|
||||
Reference in New Issue
Block a user