sync

package
v1.5.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 1, 2026 License: MIT Imports: 26 Imported by: 0

Documentation

Overview

ABOUTME: Calendar API client setup for Google Calendar integration ABOUTME: Creates authenticated Calendar service from OAuth token

ABOUTME: Calendar event importer from Google Calendar API ABOUTME: Handles pagination, sync tokens, and progress logging for calendar events

ABOUTME: Google Contacts API importer ABOUTME: Fetches and imports contacts from Google People API with deduplication

ABOUTME: Google Gmail API client for email sync ABOUTME: Creates authenticated Gmail API service for fetching high-signal emails

ABOUTME: Gmail filtering logic for high-signal email detection ABOUTME: Filters out newsletters, automated emails, and group messages

ABOUTME: Gmail importer for high-signal email interactions ABOUTME: Imports replied-to and starred emails as interactions with contacts

ABOUTME: Contact deduplication and matching logic ABOUTME: Finds existing contacts by email to prevent duplicates during sync

ABOUTME: OAuth configuration and token management for Google APIs ABOUTME: Handles OAuth flow, token storage at XDG paths, and auto-refresh

ABOUTME: Google People API client for contacts sync ABOUTME: Creates authenticated People API service for fetching Google Contacts

ABOUTME: Shared test utilities for sync package ABOUTME: Provides common test database setup and helper functions

ABOUTME: Vault configuration and credential management for suite sync integration ABOUTME: Handles vault config storage at XDG paths, environment variable overrides, and device ID generation

Index

Constants

View Source
const (
	EntityContact        = "contact"
	EntityCompany        = "company"
	EntityDeal           = "deal"
	EntityDealNote       = "deal_note"
	EntityRelationship   = "relationship"
	EntityInteractionLog = "interaction_log"
	EntityContactCadence = "contact_cadence"
	EntitySuggestion     = "suggestion"
)

Entity name constants for vault sync.

View Source
const AppID = "e9240d3f-967d-485e-8c63-e0adf7eecca0"

AppID is the namespace UUID for pagen sync data.

Variables

This section is empty.

Functions

func BuildHighSignalQuery

func BuildHighSignalQuery(userEmail string, since time.Time) string

BuildHighSignalQuery builds a Gmail API query for high-signal emails only.

func ExtractEmailAddress

func ExtractEmailAddress(emailField string) (name string, email string, domain string)

ExtractEmailAddress extracts clean email from "Name <email@domain.com>" format.

func GenerateVaultDeviceID added in v0.1.10

func GenerateVaultDeviceID() string

GenerateVaultDeviceID generates a new ULID for device identification.

func GetClient

func GetClient(ctx context.Context) (*oauth2.Config, error)

GetClient returns an authenticated HTTP client.

func ImportCalendar

func ImportCalendar(database *sql.DB, client *calendar.Service, initial bool) error

ImportCalendar fetches and imports calendar events from Google Calendar.

func ImportContacts

func ImportContacts(database *sql.DB, client *people.Service) error

ImportContacts fetches and imports contacts from Google People API.

func ImportGmail

func ImportGmail(database *sql.DB, client *gmail.Service, initial bool) error

ImportGmail fetches and imports high-signal emails from Gmail.

func IsHighSignalEmail

func IsHighSignalEmail(message *gmail.Message, userEmail string) (bool, string)

IsHighSignalEmail checks if an email meets high-signal criteria.

func LoadToken

func LoadToken() (*oauth2.Token, error)

LoadToken loads OAuth token from XDG data directory.

func NewCalendarClient

func NewCalendarClient(token *oauth2.Token) (*calendar.Service, error)

NewCalendarClient creates a Google Calendar API service from an OAuth token.

func NewGmailClient

func NewGmailClient(token *oauth2.Token) (*gmail.Service, error)

NewGmailClient creates a new Google Gmail API client.

func NewOAuthConfig

func NewOAuthConfig() *oauth2.Config

NewOAuthConfig creates OAuth2 config for Google APIs.

func NewPeopleClient

func NewPeopleClient(token *oauth2.Token) (*people.Service, error)

NewPeopleClient creates a new Google People API client.

func SaveToken

func SaveToken(token *oauth2.Token) error

SaveToken saves OAuth token to XDG data directory.

func SaveVaultConfig added in v0.1.10

func SaveVaultConfig(cfg *VaultConfig) error

SaveVaultConfig saves vault configuration to XDG data directory.

func TokenPath

func TokenPath() string

TokenPath returns XDG-compliant path for storing OAuth tokens.

func VaultConfigDir added in v0.1.10

func VaultConfigDir() string

VaultConfigDir returns XDG-compliant directory for vault configuration.

func VaultConfigPath added in v0.1.10

func VaultConfigPath() string

VaultConfigPath returns XDG-compliant path for storing vault configuration.

Types

type CompanyPayload added in v0.1.10

type CompanyPayload struct {
	ID       string `json:"id"`
	Name     string `json:"name"`
	Domain   string `json:"domain,omitempty"`
	Industry string `json:"industry,omitempty"`
	Notes    string `json:"notes,omitempty"`
}

CompanyPayload represents a company entity.

type ContactCadencePayload added in v0.1.10

type ContactCadencePayload struct {
	ID                   string `json:"id"`
	ContactName          string `json:"contact_name"` // denormalized from ContactID
	CadenceDays          int    `json:"cadence_days"`
	RelationshipStrength string `json:"relationship_strength"`
	PriorityScore        int    `json:"priority_score"`
}

ContactCadencePayload represents follow-up cadence settings for a contact.

type ContactMatcher

type ContactMatcher struct {
	// contains filtered or unexported fields
}

func NewContactMatcher

func NewContactMatcher(contacts []models.Contact) *ContactMatcher

NewContactMatcher creates a matcher from existing contacts.

func (*ContactMatcher) AddContact

func (m *ContactMatcher) AddContact(contact *models.Contact)

AddContact adds a newly created contact to the matcher to prevent duplicates within the same import session.

func (*ContactMatcher) FindMatch

func (m *ContactMatcher) FindMatch(email, name string) (*models.Contact, bool)

FindMatch looks for existing contact by email.

type ContactPayload added in v0.1.10

type ContactPayload struct {
	ID              string  `json:"id"`
	Name            string  `json:"name"`
	Email           string  `json:"email,omitempty"`
	Phone           string  `json:"phone,omitempty"`
	CompanyID       string  `json:"company_id,omitempty"`
	CompanyName     string  `json:"company_name,omitempty"`
	Notes           string  `json:"notes,omitempty"`
	LastContactedAt *string `json:"last_contacted_at,omitempty"` // RFC3339 timestamp
}

ContactPayload represents a contact with denormalized company name. Self-contained so it can be synced even if the company hasn't been synced yet.

type ContactsImporter

type ContactsImporter struct {
	// contains filtered or unexported fields
}

func NewContactsImporter

func NewContactsImporter(database *sql.DB) *ContactsImporter

func (*ContactsImporter) ImportContact

func (ci *ContactsImporter) ImportContact(gc *GoogleContact) (bool, error)

ImportContact imports a single contact from Google.

type DealNotePayload added in v0.1.10

type DealNotePayload struct {
	ID              string `json:"id"`
	DealID          string `json:"deal_id"`
	DealTitle       string `json:"deal_title"` // denormalized from DealID
	DealCompanyID   string `json:"deal_company_id,omitempty"`
	DealCompanyName string `json:"deal_company_name,omitempty"`
	Content         string `json:"content"`
	CreatedAt       string `json:"created_at"` // RFC3339 timestamp
}

DealNotePayload represents a note attached to a deal.

type DealPayload added in v0.1.10

type DealPayload struct {
	ID                string  `json:"id"`
	Title             string  `json:"title"`
	Amount            int64   `json:"amount"` // cents
	Currency          string  `json:"currency"`
	Stage             string  `json:"stage"`
	CompanyID         string  `json:"company_id,omitempty"`
	CompanyName       string  `json:"company_name,omitempty"` // denormalized from CompanyID
	ContactID         string  `json:"contact_id,omitempty"`
	ContactName       string  `json:"contact_name,omitempty"`        // denormalized from ContactID
	ExpectedCloseDate *string `json:"expected_close_date,omitempty"` // RFC3339 timestamp
}

DealPayload represents a deal with denormalized company and contact names. Self-contained so it can be synced independently of related entities.

type GoogleContact

type GoogleContact struct {
	ResourceName string
	Name         string
	Email        string
	Phone        string
	Company      string
	JobTitle     string
	Notes        string
}

type InteractionLogPayload added in v0.1.10

type InteractionLogPayload struct {
	ID              string  `json:"id"`
	ContactID       string  `json:"contact_id,omitempty"`
	ContactName     string  `json:"contact_name"` // denormalized from ContactID
	InteractionType string  `json:"interaction_type"`
	InteractedAt    string  `json:"interacted_at"` // RFC3339 timestamp
	Sentiment       *string `json:"sentiment,omitempty"`
	Metadata        string  `json:"metadata,omitempty"` // JSON string
}

InteractionLogPayload represents an interaction record.

type RelationshipPayload added in v0.1.10

type RelationshipPayload struct {
	ID               string `json:"id"`
	ContactID1       string `json:"contact_id_1,omitempty"`
	ContactID2       string `json:"contact_id_2,omitempty"`
	Contact1Name     string `json:"contact1_name"` // denormalized from ContactID1
	Contact2Name     string `json:"contact2_name"` // denormalized from ContactID2
	RelationshipType string `json:"relationship_type"`
	Context          string `json:"context,omitempty"`
}

RelationshipPayload represents a bidirectional relationship between contacts.

type SuggestionPayload added in v0.1.10

type SuggestionPayload struct {
	ID            string  `json:"id"`
	Type          string  `json:"type"`
	Content       string  `json:"content"` // JSON string containing suggestion data
	Confidence    float64 `json:"confidence"`
	SourceService string  `json:"source_service"`
	Status        string  `json:"status"`
}

SuggestionPayload represents an AI suggestion.

type VaultConfig added in v0.1.10

type VaultConfig struct {
	Server       string `json:"server"`
	UserID       string `json:"user_id"`
	Token        string `json:"token"`
	RefreshToken string `json:"refresh_token,omitempty"`
	TokenExpires string `json:"token_expires,omitempty"`
	DerivedKey   string `json:"derived_key"` // hex-encoded seed, NOT the mnemonic
	DeviceID     string `json:"device_id"`
	VaultDB      string `json:"vault_db"`
	AutoSync     bool   `json:"auto_sync"`
}

VaultConfig stores vault server credentials and synchronization settings.

func LoadVaultConfig added in v0.1.10

func LoadVaultConfig() (*VaultConfig, error)

LoadVaultConfig loads vault configuration from XDG data directory. Returns empty config with default VaultDB if file not found. Environment variables override file values: - PAGEN_VAULT_SERVER - PAGEN_VAULT_TOKEN - PAGEN_VAULT_USER_ID - PAGEN_VAULT_DEVICE_ID - PAGEN_VAULT_AUTO_SYNC.

func (*VaultConfig) IsConfigured added in v0.1.10

func (c *VaultConfig) IsConfigured() bool

IsConfigured checks if vault is properly configured with required credentials. v0.3+ requires DeviceID for all authenticated requests.

type VaultSyncer added in v0.1.10

type VaultSyncer struct {
	// contains filtered or unexported fields
}

VaultSyncer manages bidirectional synchronization with vault server.

func NewVaultSyncer added in v0.1.10

func NewVaultSyncer(cfg *VaultConfig, appDB *sql.DB) (*VaultSyncer, error)

NewVaultSyncer creates a new vault syncer instance.

func (*VaultSyncer) Close added in v0.1.10

func (s *VaultSyncer) Close() error

Close closes the vault store.

func (*VaultSyncer) LastSyncedSeq added in v0.1.10

func (s *VaultSyncer) LastSyncedSeq(ctx context.Context) (int64, error)

LastSyncedSeq returns the last synced sequence number.

func (*VaultSyncer) PendingChanges added in v0.1.10

func (s *VaultSyncer) PendingChanges(ctx context.Context) ([]vault.OutboxItem, error)

PendingChanges returns the list of pending outbox items.

func (*VaultSyncer) PendingCount added in v0.1.10

func (s *VaultSyncer) PendingCount(ctx context.Context) (int, error)

PendingCount returns the number of pending changes in the outbox.

func (*VaultSyncer) QueueCompanyChange added in v0.1.10

func (s *VaultSyncer) QueueCompanyChange(ctx context.Context, company *models.Company, op vault.Op) error

QueueCompanyChange queues a company change for sync.

func (*VaultSyncer) QueueContactCadenceChange added in v0.1.10

func (s *VaultSyncer) QueueContactCadenceChange(ctx context.Context, cadence *models.ContactCadence, contactName string, op vault.Op) error

QueueContactCadenceChange queues a contact cadence change for sync.

func (*VaultSyncer) QueueContactChange added in v0.1.10

func (s *VaultSyncer) QueueContactChange(ctx context.Context, contact *models.Contact, companyName string, op vault.Op) error

QueueContactChange queues a contact change for sync.

func (*VaultSyncer) QueueDealChange added in v0.1.10

func (s *VaultSyncer) QueueDealChange(ctx context.Context, deal *models.Deal, companyName, contactName string, op vault.Op) error

QueueDealChange queues a deal change for sync.

func (*VaultSyncer) QueueDealNoteChange added in v0.1.10

func (s *VaultSyncer) QueueDealNoteChange(ctx context.Context, note *models.DealNote, dealTitle string, op vault.Op) error

QueueDealNoteChange queues a deal note change for sync.

func (*VaultSyncer) QueueInteractionLogChange added in v0.1.10

func (s *VaultSyncer) QueueInteractionLogChange(ctx context.Context, interaction *models.InteractionLog, contactName string, op vault.Op) error

QueueInteractionLogChange queues an interaction log change for sync.

func (*VaultSyncer) QueueRelationshipChange added in v0.1.10

func (s *VaultSyncer) QueueRelationshipChange(ctx context.Context, rel *models.Relationship, contact1Name, contact2Name string, op vault.Op) error

QueueRelationshipChange queues a relationship change for sync.

func (*VaultSyncer) QueueSuggestionChange added in v0.1.10

func (s *VaultSyncer) QueueSuggestionChange(ctx context.Context, suggestion *models.Suggestion, op vault.Op) error

QueueSuggestionChange queues a suggestion change for sync.

func (*VaultSyncer) Sync added in v0.1.10

func (s *VaultSyncer) Sync(ctx context.Context) error

Sync performs a full bidirectional sync without events.

func (*VaultSyncer) SyncWithEvents added in v0.1.10

func (s *VaultSyncer) SyncWithEvents(ctx context.Context, events vault.SyncEvents) error

SyncWithEvents performs a full bidirectional sync with event callbacks.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL