fix(HH-528): persist auto resolve message (#116)

Co-authored-by: Rogee <rogee@ipao.vip>
This commit is contained in:
Rogee
2026-08-23 16:54:20 +08:00
committed by GitHub
co-authored by rogee
parent 5a61aac1f2
commit 3aac701495
7 changed files with 41 additions and 6 deletions
@@ -72,7 +72,7 @@ func TestUploadPostgresProductionMigrationsFromEmptySchema(t *testing.T) {
require.NoError(t, RunMigrations(dbURL, productionMigrationsPath(t)))
version, dirty, err := CurrentVersion(dbURL, productionMigrationsPath(t))
require.NoError(t, err)
assert.Equal(t, uint(84), version)
assert.Equal(t, uint(85), version)
assert.False(t, dirty)
exerciseUploadProductionSchema(t, db)
}
@@ -469,7 +469,7 @@ func serializeAccountSettings(account *model.Account) map[string]any {
settings := map[string]any{
"auto_resolve_after": account.AutoResolveDuration,
"auto_resolve_duration": account.AutoResolveDuration,
"auto_resolve_message": "",
"auto_resolve_message": account.AutoResolveMessage,
"auto_resolve_ignore_waiting": account.AutoResolveIgnoreWaiting,
"audio_transcriptions": account.AudioTranscriptions,
"auto_resolve_label": account.AutoResolveLabel,
@@ -349,10 +349,11 @@ func (s *AccountHandlerTestSuite) TestPatchUpdate_AudioTranscriptions() {
func (s *AccountHandlerTestSuite) TestPatchUpdate_AutoResolvePreferences() {
acc := s.seedAccount("Auto Resolve Preferences")
accountURL := "/api/v1/accounts/" + strconv.FormatUint(uint64(acc.ID), 10)
body := `{"auto_resolve_after":15,"auto_resolve_ignore_waiting":true,"auto_resolve_label":"vip"}`
body := `{"auto_resolve_after":15,"auto_resolve_ignore_waiting":true,"auto_resolve_label":"vip","auto_resolve_message":"We will close this conversation now."}`
w := httptest.NewRecorder()
req, _ := http.NewRequest("PATCH", "/api/v1/accounts/"+strconv.FormatUint(uint64(acc.ID), 10), bytes.NewBufferString(body))
req, _ := http.NewRequest("PATCH", accountURL, bytes.NewBufferString(body))
req.Header.Set("Content-Type", "application/json")
s.router.ServeHTTP(w, req)
@@ -362,16 +363,25 @@ func (s *AccountHandlerTestSuite) TestPatchUpdate_AutoResolvePreferences() {
assert.Equal(s.T(), float64(15), settings["auto_resolve_after"])
assert.Equal(s.T(), true, settings["auto_resolve_ignore_waiting"])
assert.Equal(s.T(), "vip", settings["auto_resolve_label"])
assert.Equal(s.T(), "We will close this conversation now.", settings["auto_resolve_message"])
var stored model.Account
require.NoError(s.T(), s.db.First(&stored, acc.ID).Error)
assert.Equal(s.T(), 15, stored.AutoResolveDuration)
assert.True(s.T(), stored.AutoResolveIgnoreWaiting)
assert.Equal(s.T(), "vip", stored.AutoResolveLabel)
assert.Equal(s.T(), "We will close this conversation now.", stored.AutoResolveMessage)
w = httptest.NewRecorder()
req, _ = http.NewRequest("GET", accountURL, nil)
s.router.ServeHTTP(w, req)
require.Equal(s.T(), http.StatusOK, w.Code)
settings = s.unmarshalResponse(w)["settings"].(map[string]interface{})
assert.Equal(s.T(), "We will close this conversation now.", settings["auto_resolve_message"])
body = `{"auto_resolve_after":0,"auto_resolve_ignore_waiting":false,"auto_resolve_label":""}`
w = httptest.NewRecorder()
req, _ = http.NewRequest("PATCH", "/api/v1/accounts/"+strconv.FormatUint(uint64(acc.ID), 10), bytes.NewBufferString(body))
req, _ = http.NewRequest("PATCH", accountURL, bytes.NewBufferString(body))
req.Header.Set("Content-Type", "application/json")
s.router.ServeHTTP(w, req)
@@ -380,6 +390,23 @@ func (s *AccountHandlerTestSuite) TestPatchUpdate_AutoResolvePreferences() {
assert.Zero(s.T(), stored.AutoResolveDuration)
assert.False(s.T(), stored.AutoResolveIgnoreWaiting)
assert.Empty(s.T(), stored.AutoResolveLabel)
assert.Equal(s.T(), "We will close this conversation now.", stored.AutoResolveMessage)
body = `{"auto_resolve_message":""}`
w = httptest.NewRecorder()
req, _ = http.NewRequest("PATCH", accountURL, bytes.NewBufferString(body))
req.Header.Set("Content-Type", "application/json")
s.router.ServeHTTP(w, req)
require.Equal(s.T(), http.StatusOK, w.Code)
settings = s.unmarshalResponse(w)["settings"].(map[string]interface{})
assert.Empty(s.T(), settings["auto_resolve_message"])
w = httptest.NewRecorder()
req, _ = http.NewRequest("GET", accountURL, nil)
s.router.ServeHTTP(w, req)
require.Equal(s.T(), http.StatusOK, w.Code)
settings = s.unmarshalResponse(w)["settings"].(map[string]interface{})
assert.Empty(s.T(), settings["auto_resolve_message"])
}
func (s *AccountHandlerTestSuite) TestPatchUpdate_ChatwootGeneralSettingsPayload() {
+1
View File
@@ -22,6 +22,7 @@ type Account struct {
AutoResolveDuration int `gorm:"default:0" json:"auto_resolve_duration,omitempty"` // minutes
AutoResolveIgnoreWaiting bool `gorm:"default:false" json:"auto_resolve_ignore_waiting"`
AutoResolveLabel string `gorm:"size:255" json:"auto_resolve_label,omitempty"`
AutoResolveMessage string `gorm:"type:text;not null;default:''" json:"auto_resolve_message,omitempty"`
AudioTranscriptions bool `gorm:"default:false" json:"audio_transcriptions"`
Limits datatypes.JSON `gorm:"type:jsonb;default:'{}'" json:"limits,omitempty"` // Chatwoot account limits, e.g. emails
AgentLimit int `gorm:"default:0" json:"agent_limit,omitempty"` // max agents allowed (0 = unlimited), Chatwoot usage_limits[:agents]
+4 -1
View File
@@ -242,7 +242,7 @@ type UpdateAccountRequest struct {
Status string `json:"status,omitempty" validate:"omitempty,oneof=active inactive"`
AutoResolveDuration *int `json:"auto_resolve_duration,omitempty" validate:"omitempty,gte=0"`
AutoResolveAfter *int `json:"auto_resolve_after,omitempty" validate:"omitempty,gte=0"`
AutoResolveMessage string `json:"auto_resolve_message,omitempty"`
AutoResolveMessage *string `json:"auto_resolve_message,omitempty"`
AutoResolveIgnoreWaiting *bool `json:"auto_resolve_ignore_waiting,omitempty"`
AudioTranscriptions *bool `json:"audio_transcriptions,omitempty"`
AutoResolveLabel *string `json:"auto_resolve_label,omitempty"`
@@ -298,6 +298,9 @@ func (s *AccountService) Update(ctx context.Context, id uint, req UpdateAccountR
if req.AutoResolveLabel != nil {
account.AutoResolveLabel = *req.AutoResolveLabel
}
if req.AutoResolveMessage != nil {
account.AutoResolveMessage = *req.AutoResolveMessage
}
if req.AudioTranscriptions != nil {
account.AudioTranscriptions = *req.AudioTranscriptions
}
@@ -0,0 +1,2 @@
ALTER TABLE accounts
DROP COLUMN IF EXISTS auto_resolve_message;
@@ -0,0 +1,2 @@
ALTER TABLE accounts
ADD COLUMN IF NOT EXISTS auto_resolve_message TEXT NOT NULL DEFAULT '';