fix(chat): enable chat operations and make mute duration configurable#36
Open
edilsonoliveirama wants to merge 3 commits intoEvolutionAPI:mainfrom
Open
fix(chat): enable chat operations and make mute duration configurable#36edilsonoliveirama wants to merge 3 commits intoEvolutionAPI:mainfrom
edilsonoliveirama wants to merge 3 commits intoEvolutionAPI:mainfrom
Conversation
The /manager dashboard previously showed only a static placeholder
("Dashboard content will be implemented here..."). This replaces it
with a standalone HTML page that fetches live data from the API and
displays real metrics:
- Total instances count
- Connected instances count and percentage
- Disconnected instances count
- Server health status (GET /server/ok)
- AlwaysOnline count
- Instance table with name, status badge, phone number, client and
AlwaysOnline indicator
- Auto-refresh every 30 seconds with manual refresh button
Implementation uses a standalone HTML file (Tailwind CDN + vanilla JS
fetch) served at GET /manager, keeping the existing compiled bundle
intact for all other routes (/manager/instances, /manager/login, etc.).
Changes:
- manager/dashboard/index.html: new self-contained dashboard page
- pkg/routes/routes.go: serve dashboard/index.html for GET /manager
(exact), keep dist/index.html for GET /manager/*any (wildcard)
- Dockerfile: copy manager/dashboard/ into the final image
- .gitignore: exclude manager build artifacts from version control
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Reviewer's GuideEnables and documents fully functional chat management endpoints while making chat mute duration configurable, and adds a new static dashboard page with routing and Docker packaging updates. Sequence diagram for configurable chat mute operationsequenceDiagram
actor Caller
participant API as GinRouter
participant Handler as chatHandler
participant Service as chatService
participant Instance as instance_model_Instance
participant WAClient as WhatsAppClient
Caller->>API: POST /chat/mute { chat, optional duration }
API->>Handler: ChatMute(ctx)
Handler->>Service: ChatMute(data *BodyStruct, instance *instance_model_Instance)
Service->>Service: validate chat JID
alt invalid chat
Service-->>Handler: error "invalid phone number"
Handler-->>API: HTTP 400
API-->>Caller: HTTP 400
else valid chat
Service->>WAClient: SendAppState(appstate.BuildMute(recipient, true, durationSeconds * time.Second))
alt SendAppState success
Service-->>Handler: success
Handler-->>API: HTTP 200
API-->>Caller: HTTP 200
else SendAppState error
Service-->>Handler: error
Handler-->>API: HTTP 500
API-->>Caller: HTTP 500
end
end
Class diagram for updated chat service typesclassDiagram
class BodyStruct {
string Chat
int64 Duration
}
class HistorySyncRequestStruct {
string Page
string Cursor
string Limit
}
class chatService {
+ChatMute(data *BodyStruct, instance *instance_model_Instance) string
+ChatPin(data *BodyStruct, instance *instance_model_Instance) string
+ChatUnpin(data *BodyStruct, instance *instance_model_Instance) string
+ChatArchive(data *BodyStruct, instance *instance_model_Instance) string
+ChatUnarchive(data *BodyStruct, instance *instance_model_Instance) string
+ChatUnmute(data *BodyStruct, instance *instance_model_Instance) string
+HistorySyncRequest(data *HistorySyncRequestStruct, instance *instance_model_Instance) string
}
class instance_model_Instance {
string Id
string Jid
bool Connected
bool AlwaysOnline
string ClientName
}
chatService --> BodyStruct : uses
chatService --> HistorySyncRequestStruct : uses
chatService --> instance_model_Instance : operates_on
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 1 issue
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="pkg/chat/service/chat_service.go" line_range="189-190" />
<code_context>
}
- err = client.SendAppState(context.Background(), appstate.BuildMute(recipient, true, 1*time.Hour))
+ muteDuration := time.Duration(data.Duration) * time.Second
+ err = client.SendAppState(context.Background(), appstate.BuildMute(recipient, true, muteDuration))
if err != nil {
c.loggerWrapper.GetLogger(instance.Id).LogError("[%s] error mute chat: %v", instance.Id, err)
</code_context>
<issue_to_address>
**issue:** Clarify and guard mute duration semantics (0/negative and very large values).
`data.Duration` is passed straight into `time.Duration(data.Duration) * time.Second` and then to `BuildMute` with no validation or special handling.
Please explicitly:
- Reject `Duration < 0` with a validation error.
- Map `Duration == 0` to whatever `BuildMute`/WhatsApp expects for “mute forever” (rather than `0 * time.Second` if that does not mean forever).
- Consider clamping excessively large values if the underlying API has practical limits.
This will align the implementation with the documented semantics and avoid surprising behavior when the field is omitted or misused.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Removes the '// TODO: not working' markers from the six chat endpoints (pin, unpin, archive, unarchive, mute, unmute). Investigation confirmed the implementation is correct: the endpoints work on fully-established sessions that have synced WhatsApp app state keys. The markers were likely added after testing on a fresh session where keys had not yet been distributed by the WhatsApp server. Also fixes the hardcoded 1-hour mute duration: the BodyStruct now accepts an optional `duration` field (seconds). Sending 0 or omitting the field mutes the chat indefinitely, matching WhatsApp's own behaviour.
79948c6 to
bd9f000
Compare
Reject negative duration values with a 400-level validation error. Document that duration=0 maps to 'mute forever' (BuildMute treats 0 as a zero time.Duration, which causes BuildMuteAbs to set the WhatsApp sentinel timestamp of -1). Clamp duration to a maximum of 1 year (31536000 seconds) to avoid unreasonably large timestamps being sent to the WhatsApp API.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
O que foi investigado
Os seis endpoints de chat (POST /chat/pin, /unpin, /archive, /unarchive, /mute, /unmute) estavam todos marcados como
// TODO: not workingno router.Após rastrear o caminho completo da execução — do handler ao service e ao
SendAppStatedo whatsmeow — a conclusão é:A implementação estava correta. Os endpoints funcionam em qualquer sessão WhatsApp estabelecida que tenha sincronizado as app state keys (ou seja, qualquer sessão normal após o login por QR). Os comentários
// TODOparecem ter sido adicionados após testes em sessão recém-criada, onde o servidor WhatsApp ainda não havia distribuído as keys — causando o erro"no app state keys found". Essa é uma limitação da biblioteca whatsmeow para criação de novas keys, não um bug no evolution-go.O que foi alterado
pkg/routes/routes.goRemovidos os seis comentários
// TODO: not working. Os endpoints são funcionais para sessões estabelecidas.pkg/chat/service/chat_service.goduration(int64, segundos) noBodyStruct.ChatMuteagora usadurationdo request em vez do hardcoded1 * time.Hour.duration: 0(ou omitir o campo) silencia o chat indefinidamente — consistente com o comportamento do próprio WhatsApp.pkg/chat/handler/chat_handler.goAtualizada a descrição Swagger do
POST /chat/mutepara documentar o campoduration.O que NÃO foi corrigido (e por quê)
Se uma sessão nunca recebeu app state keys do servidor WhatsApp (ex: sessão nova ou corrompida), os seis endpoints ainda retornarão erro. Isso é uma limitação conhecida do whatsmeow (
// TODO create new key instead of reusing the primary client's keysemappstate.go). O erro agora é surfaceado claramente ao caller via HTTP 500.Breaking changes
Nenhum. O campo
durationem/chat/muteé opcional e tem default0(silenciar para sempre), que é um default melhor do que a hora hardcoded anterior.Summary by Sourcery
Add a standalone manager dashboard with real-time instance metrics and enable configurable mute duration for chat operations.
New Features:
Enhancements:
Build:
Documentation: