From 94c0fa9bdc9fd9e05a9f70c43f76e55755d0bb55 Mon Sep 17 00:00:00 2001 From: walterdiazpalaestra Date: Fri, 8 May 2026 20:50:27 -0600 Subject: [PATCH] feat(events): forward Picture, UserAbout, BusinessName webhook events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three whatsmeow events were silently dropped by the dispatcher ("Unhandled event" log) because the central switch in pkg/whatsmeow/service/whatsmeow.go had no case for them, even though the underlying go.mau.fi/whatsmeow library emits them: - *events.Picture (types/events/events.go) — fires when any user's profile picture or any group's photo changes. Carries JID, Author, Timestamp, Remove, PictureID. Useful for keeping CRM avatar caches in sync without polling /chat/fetchProfilePictureUrl per contact. - *events.UserAbout (types/events/events.go) — fires when any user's "about" / status text changes. Carries JID, Status, Timestamp. - *events.BusinessName (types/events/appstate.go) — fires lazily on inbound messages whose verified business name differs from the cached one. Carries JID, OldBusinessName, NewBusinessName. Changes: 1. pkg/whatsmeow/service/whatsmeow.go — added three new cases to the myEventHandler dispatch switch, mirroring the minimal style of the existing *events.Contact / *events.PushName handlers (set doWebhook and postMap["event"]; the raw event is already attached at line 850 via postMap["data"] = rawEvt). 2. pkg/whatsmeow/service/whatsmeow.go (CallWebhook) — added three new case branches on eventType so consumers can subscribe to PICTURE / USER_ABOUT / BUSINESS_NAME independently. Following the existing per-category split (e.g. MESSAGE vs SEND_MESSAGE vs READ_RECEIPT) rather than folding into CONTACT. 3. pkg/internal/event_types/event_types.go — added the three new subscription category constants to the const block, AllEventTypes slice, and validEventTypes map so IsEventType accepts them. The change is purely additive: existing subscribers keep receiving exactly what they did before. Consumers wanting the new events must opt in by including PICTURE / USER_ABOUT / BUSINESS_NAME in their subscribe list (or use ALL). No new dependencies, no behavior changes to existing events. Build verified with `go build ./...` against the pinned whatsmeow-lib submodule (0923702fb3fac8525241f15331b92116485d69eb). --- pkg/internal/event_types/event_types.go | 9 +++++++++ pkg/whatsmeow/service/whatsmeow.go | 24 ++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/pkg/internal/event_types/event_types.go b/pkg/internal/event_types/event_types.go index 3f7a632..8c7569a 100644 --- a/pkg/internal/event_types/event_types.go +++ b/pkg/internal/event_types/event_types.go @@ -16,6 +16,9 @@ const ( NEWSLETTER = "NEWSLETTER" QRCODE = "QRCODE" BUTTON_CLICK = "BUTTON_CLICK" + PICTURE = "PICTURE" + USER_ABOUT = "USER_ABOUT" + BUSINESS_NAME = "BUSINESS_NAME" ) var AllEventTypes = []string{ @@ -33,6 +36,9 @@ var AllEventTypes = []string{ NEWSLETTER, QRCODE, BUTTON_CLICK, + PICTURE, + USER_ABOUT, + BUSINESS_NAME, } var validEventTypes = map[string]bool{ @@ -51,6 +57,9 @@ var validEventTypes = map[string]bool{ NEWSLETTER: true, QRCODE: true, BUTTON_CLICK: true, + PICTURE: true, + USER_ABOUT: true, + BUSINESS_NAME: true, } func IsEventType(eventType string) bool { diff --git a/pkg/whatsmeow/service/whatsmeow.go b/pkg/whatsmeow/service/whatsmeow.go index 78ec6c1..949a69b 100644 --- a/pkg/whatsmeow/service/whatsmeow.go +++ b/pkg/whatsmeow/service/whatsmeow.go @@ -1898,6 +1898,15 @@ func (mycli *MyClient) myEventHandler(rawEvt interface{}) { case *events.PushName: doWebhook = true postMap["event"] = "PushName" + case *events.Picture: + doWebhook = true + postMap["event"] = "Picture" + case *events.UserAbout: + doWebhook = true + postMap["event"] = "UserAbout" + case *events.BusinessName: + doWebhook = true + postMap["event"] = "BusinessName" case *events.IdentityChange: doWebhook = false case *events.GroupInfo: @@ -2127,6 +2136,21 @@ func (w *whatsmeowService) CallWebhook(instance *instance_model.Instance, queueN w.loggerWrapper.GetLogger(instance.Id).LogInfo("[%s] Event received of type %s", instance.Id, eventType) w.sendToQueueOrWebhook(instance, queueName, jsonData) } + case "Picture": + if contains(subscriptions, "PICTURE") { + w.loggerWrapper.GetLogger(instance.Id).LogInfo("[%s] Event received of type %s", instance.Id, eventType) + w.sendToQueueOrWebhook(instance, queueName, jsonData) + } + case "UserAbout": + if contains(subscriptions, "USER_ABOUT") { + w.loggerWrapper.GetLogger(instance.Id).LogInfo("[%s] Event received of type %s", instance.Id, eventType) + w.sendToQueueOrWebhook(instance, queueName, jsonData) + } + case "BusinessName": + if contains(subscriptions, "BUSINESS_NAME") { + w.loggerWrapper.GetLogger(instance.Id).LogInfo("[%s] Event received of type %s", instance.Id, eventType) + w.sendToQueueOrWebhook(instance, queueName, jsonData) + } default: return