mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-10-13 22:15:47 +00:00
feat(store): add thread support to contact model and collector
- Add threadID and threadType to ContactCollector.EnsureContact - Update ContactStore.UpsertContact signature - Update Contact type in web UI
This commit is contained in:
1 parent
670000651d
commit
bf98a32e9b
3 files changed
+14
-8
No files matched your search
@@ -23,16 +23,17 @@ func NewContactCollector(s ContactStore, c cache.Cache[bool]) *ContactCollector
|
||||
}
|
||||
|
||||
// EnsureContact creates or refreshes a contact entry, skipping DB if recently seen.
|
||||
// contactType: "user" (individual sender) or "group" (group chat entity).
|
||||
func (c *ContactCollector) EnsureContact(ctx context.Context, channelType, channelInstance, senderID, userID, displayName, username, peerKind, contactType string) {
|
||||
key := channelType + ":" + senderID
|
||||
// contactType: "user" (individual sender), "group" (group chat entity), or "topic" (forum topic).
|
||||
// Pass empty threadID/threadType for base contacts (DM, group root).
|
||||
func (c *ContactCollector) EnsureContact(ctx context.Context, channelType, channelInstance, senderID, userID, displayName, username, peerKind, contactType, threadID, threadType string) {
|
||||
key := channelType + ":" + senderID + ":" + threadID
|
||||
if _, ok := c.seen.Get(ctx, key); ok {
|
||||
return
|
||||
}
|
||||
if contactType == "" {
|
||||
contactType = "user"
|
||||
}
|
||||
if err := c.store.UpsertContact(ctx, channelType, channelInstance, senderID, userID, displayName, username, peerKind, contactType); err != nil {
|
||||
if err := c.store.UpsertContact(ctx, channelType, channelInstance, senderID, userID, displayName, username, peerKind, contactType, threadID, threadType); err != nil {
|
||||
slog.Warn("contact_collector.upsert_failed", "error", err, "channel", channelType, "sender", senderID)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -19,7 +19,9 @@ type ChannelContact struct {
|
||||
Username *string `json:"username,omitempty"`
|
||||
AvatarURL *string `json:"avatar_url,omitempty"`
|
||||
PeerKind *string `json:"peer_kind,omitempty"`
|
||||
ContactType string `json:"contact_type"` // "user" or "group"
|
||||
ContactType string `json:"contact_type"` // "user", "group", or "topic"
|
||||
ThreadID *string `json:"thread_id,omitempty"`
|
||||
ThreadType *string `json:"thread_type,omitempty"`
|
||||
MergedID *uuid.UUID `json:"merged_id,omitempty"`
|
||||
FirstSeenAt time.Time `json:"first_seen_at"`
|
||||
LastSeenAt time.Time `json:"last_seen_at"`
|
||||
@@ -37,9 +39,10 @@ type ContactListOpts struct {
|
||||
|
||||
// ContactStore manages channel contacts (auto-collected user info).
|
||||
type ContactStore interface {
|
||||
// UpsertContact creates or updates a contact. On conflict (channel_type, sender_id),
|
||||
// UpsertContact creates or updates a contact. On conflict (tenant_id, channel_type, sender_id, thread_id),
|
||||
// updates display_name, username, user_id, channel_instance, and last_seen_at.
|
||||
UpsertContact(ctx context.Context, channelType, channelInstance, senderID, userID, displayName, username, peerKind, contactType string) error
|
||||
// Pass empty threadID/threadType for base contacts (DM, group root).
|
||||
UpsertContact(ctx context.Context, channelType, channelInstance, senderID, userID, displayName, username, peerKind, contactType, threadID, threadType string) error
|
||||
|
||||
// ListContacts searches contacts with pagination and filters.
|
||||
ListContacts(ctx context.Context, opts ContactListOpts) ([]ChannelContact, error)
|
||||
|
||||
@@ -19,7 +19,9 @@ export interface ChannelContact {
|
||||
username?: string;
|
||||
avatar_url?: string;
|
||||
peer_kind?: string;
|
||||
contact_type: string; // "user" or "group"
|
||||
contact_type: string; // "user", "group", or "topic"
|
||||
thread_id?: string;
|
||||
thread_type?: string;
|
||||
merged_id?: string;
|
||||
first_seen_at: string;
|
||||
last_seen_at: string;
|
||||
|
||||
Reference in new issue
Block a user