Expose CTWA referral metadata on message webhooks#58
Open
juliomuhlbauer wants to merge 2 commits intoevolution-foundation:mainfrom
Open
Expose CTWA referral metadata on message webhooks#58juliomuhlbauer wants to merge 2 commits intoevolution-foundation:mainfrom
juliomuhlbauer wants to merge 2 commits intoevolution-foundation:mainfrom
Conversation
Reviewer's GuideExpose WhatsApp CTWA/ad referral metadata in inbound message webhooks and persist it on messages, ensuring it is preserved across status updates, with tests and docs added. Sequence diagram for exposing CTWA referral on inbound message webhookssequenceDiagram
actor User
participant AdPlatform
participant WhatsAppServer
participant MyClient
participant ReferralExtractor
participant MessageRepository
participant Database
participant WebhookEndpoint
User->>AdPlatform: Click CTWA ad
AdPlatform->>WhatsAppServer: Open chat with CTWA metadata
WhatsAppServer->>MyClient: Deliver inbound message with contextInfo.externalAdReply
MyClient->>ReferralExtractor: extractReferralFromMessage(message)
ReferralExtractor-->>MyClient: referral JSON
MyClient->>MyClient: Build dataMap with message fields
MyClient->>MyClient: Add referral to dataMap when present
MyClient->>WebhookEndpoint: POST inbound message webhook
Note over WebhookEndpoint: Payload contains data.referral
MyClient->>MessageRepository: InsertMessage(message with Referral)
MessageRepository->>Database: Upsert by message_id
Database-->>MessageRepository: Insert or update
MessageRepository-->>MyClient: Result
loop Subsequent status updates
WhatsAppServer->>MyClient: Deliver status update event
MyClient->>ReferralExtractor: extractReferralFromMessage(message)
ReferralExtractor-->>MyClient: nil referral
MyClient->>MessageRepository: InsertMessage(message without Referral)
MessageRepository->>Database: Upsert timestamp,status,source only
Database-->>MessageRepository: Existing Referral preserved
end
Entity relationship diagram for Message with referral metadataerDiagram
Message {
uuid Id PK
string MessageID "unique message id"
string Timestamp "received timestamp"
string Status "message status"
string Source "message source user"
jsonb Referral "raw CTWA referral metadata"
}
Class diagram for Message persistence and referral extractionclassDiagram
class Message {
string Id
string MessageID
string Timestamp
string Status
string Source
json.RawMessage Referral
BeforeCreate(tx *gorm.DB) error
}
class messageRepository {
*gorm.DB db
InsertMessage(message message_model.Message) error
}
class MyClient {
Config config
messageRepository messageRepository
myEventHandler(rawEvt interface_any)
}
class ReferralExtractor {
extractReferralFromMessage(message *waE2E.Message) json.RawMessage
getContextInfoFromMessage(message *waE2E.Message) *waE2E.ContextInfo
}
Message <.. messageRepository : uses
MyClient --> messageRepository : has
MyClient ..> ReferralExtractor : calls
ReferralExtractor ..> waE2E.Message : reads
ReferralExtractor ..> waE2E.ContextInfo : reads
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
myEventHandler,InsertMessageis executed in a goroutine and its error is ignored, which can hide persistence failures; consider at least logging the error or routing it through a channel so DB issues are observable. - The
Referralfield is annotated withgorm:"type:jsonb", which is Postgres-specific and may not map optimally (or at all) on other drivers like sqlite; consider letting GORM infer the type or using driver-specific tags/options to avoid cross-database issues.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `myEventHandler`, `InsertMessage` is executed in a goroutine and its error is ignored, which can hide persistence failures; consider at least logging the error or routing it through a channel so DB issues are observable.
- The `Referral` field is annotated with `gorm:"type:jsonb"`, which is Postgres-specific and may not map optimally (or at all) on other drivers like sqlite; consider letting GORM infer the type or using driver-specific tags/options to avoid cross-database issues.
## Individual Comments
### Comment 1
<location path="pkg/whatsmeow/service/whatsmeow.go" line_range="1523-1532" />
<code_context>
postMap["data"] = dataMap
+ if mycli.config.DatabaseSaveMessages {
+ message := message_model.Message{
+ MessageID: evt.Info.ID,
+ Timestamp: evt.Info.Timestamp.Format("2006-01-02 15:04:05"),
+ Status: "Received",
+ Source: evt.Info.Chat.ToNonAD().User,
+ Referral: referral,
+ }
+
+ go mycli.messageRepository.InsertMessage(message)
+ }
+
</code_context>
<issue_to_address>
**issue (bug_risk):** Consider handling or at least logging errors from async InsertMessage calls
Calling `InsertMessage` in a goroutine without checking its error means DB failures (connection issues, constraints, etc.) will be completely silent. Please either log the error inside the goroutine or use a small helper to capture and log it so we don’t risk undetected write failures.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
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.
Summary
\n- expose raw CTWA / ad referral metadata as a top-level field on inbound message webhooks\n- persist the referral JSON on inbound message records without letting later read/delivered receipts wipe it out\n- add focused tests for referral extraction and message upsert behavior\n- document the new webhook field in the events system guide\n\n## Verification\n- go test ./...
Summary by Sourcery
Expose CTWA/ad referral metadata on inbound WhatsApp messages, surface it on webhooks, persist it on message records, and ensure it is preserved across message status updates.
New Features:
referralfield in inbound message webhook payloads.Enhancements:
Build:
Documentation:
data.referralfield and its semantics in the events system guide.Tests:
Summary by Sourcery
Expose and persist CTWA/ad referral metadata on inbound messages, surface it on webhooks, and add coverage and docs for the new behavior.
New Features:
referralfield in inbound message webhook payloads.Enhancements:
Build:
Documentation:
data.referralfield and its semantics in the events system guide.Tests: