Closed
Conversation
added 2 commits
April 13, 2026 19:38
WhatsApp silently ignores edits when the message type differs from the original. SendText sends as ExtendedTextMessage, so edits must match that type instead of Conversation. This patch matches the fix already deployed in production via SSH on 2026-04-07.
Adds a new authenticated endpoint to expose whatsmeow's SendPresence
function so the client can be marked as available/unavailable without
disconnecting.
This mirrors WhatsApp Web's behavior when minimized — the linked
device stays connected but the phone resumes receiving push
notifications because WhatsApp server sees the device as inactive.
Use case: ImobDeal marks the instance unavailable when the user
leaves the WhatsApp screen, and available when they return. Enables
brokers on iPhone to receive normal push notifications without
having to manually unlink the device.
- POST /instance/presence with {"state": "available" | "unavailable"}
- Returns 400 on invalid state, 500 on internal error
- Requires the standard instance auth (apikey header)
Reviewer's GuideAdds a new presence management capability for WhatsApp instances via an HTTP endpoint and fixes message editing to use the same message type as original sends so edits are honored by WhatsApp. Sequence diagram for the new /instance/presence HTTP endpointsequenceDiagram
actor ApiClient
participant GinRouter
participant InstanceHandler
participant InstanceService
participant WhatsmeowClient
participant Logger
ApiClient->>GinRouter: POST /instance/presence { state }
GinRouter->>InstanceHandler: SetPresence(ctx)
InstanceHandler->>InstanceHandler: ctx.MustGet(instance)
InstanceHandler->>InstanceHandler: ctx.ShouldBindJSON(SetPresenceStruct)
InstanceHandler->>InstanceService: SetPresence(data, instance)
InstanceService->>InstanceService: ensureClientConnected(instance.Id)
InstanceService->>WhatsmeowClient: IsConnected()
InstanceService->>WhatsmeowClient: IsLoggedIn()
InstanceService->>WhatsmeowClient: SendPresence(state)
WhatsmeowClient-->>InstanceService: result
InstanceService->>Logger: LogInfo("Presence set to state")
InstanceService-->>InstanceHandler: nil
InstanceHandler-->>ApiClient: 200 { message: success, state }
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, and left some high level feedback:
- In
SetPresence, invalid presence state values currently bubble up from the service as a 500; consider classifying this as a client error (e.g., validate in the handler or inspect the error and return 400) so the API contract better reflects misuse vs server failure. - The new
SetPresenceandEditMessageflows usecontext.Background()for WhatsApp client calls; passing a request-scoped context (e.g., derived from the gin context) would allow cancellations/timeouts to propagate correctly. - The log message in
EditMessagestill sayserror revoking message, which is misleading for an edit operation; update the message to reflect that the edit failed.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `SetPresence`, invalid presence state values currently bubble up from the service as a 500; consider classifying this as a client error (e.g., validate in the handler or inspect the error and return 400) so the API contract better reflects misuse vs server failure.
- The new `SetPresence` and `EditMessage` flows use `context.Background()` for WhatsApp client calls; passing a request-scoped context (e.g., derived from the gin context) would allow cancellations/timeouts to propagate correctly.
- The log message in `EditMessage` still says `error revoking message`, which is misleading for an edit operation; update the message to reflect that the edit failed.
## Individual Comments
### Comment 1
<location path="pkg/instance/handler/instance_handler.go" line_range="237-238" />
<code_context>
+ return
+ }
+
+ if err := i.instanceService.SetPresence(&data, instance); err != nil {
+ ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
+ return
+ }
</code_context>
<issue_to_address>
**🚨 issue (security):** Map validation-style errors to 4xx and avoid returning raw internal error messages to clients.
Currently any `SetPresence` error results in a 500 with `err.Error()` in the response. That causes two problems: user-input errors (e.g. invalid state) should be 4xx and are documented as 400 in Swagger, and exposing `err.Error()` may leak internal details.
It’d be better to distinguish validation vs internal errors (e.g. via sentinel errors or a small error type), then:
- return 400 with a client-facing message for invalid input/state, and
- return 500 with a generic message for unexpected/internal errors, logging the detailed error server-side instead of returning it.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
- SetPresence: validate state in HTTP handler so invalid input returns 400 instead of bubbling up to 500. Service layer now trusts its input and any error it emits is treated as 5xx. - SetPresence: accept a request-scoped context.Context parameter so cancellations/timeouts from the HTTP layer propagate down to whatsmeow's SendPresence call, instead of using context.Background(). - EditMessage: fix misleading log message — was 'error revoking message', now reads 'error editing message'.
These files are used by developers to run Evolution Go locally with docker-compose without touching the Dockerfile or affecting the upstream repo. Keep them out of the fork so they don't conflict with a potential future upstream docker-compose setup.
a1a21d6 to
736d9e4
Compare
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.
Description
Related Issue
Closes #(issue_number)
Type of Change
Testing
Screenshots (if applicable)
Checklist
Additional Notes
Summary by Sourcery
Add support for managing WhatsApp presence state via the API and fix message editing compatibility with previously sent messages.
New Features:
Bug Fixes:
Enhancements: