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
- func BuildHighSignalQuery(userEmail string, since time.Time) string
- func ExtractEmailAddress(emailField string) (name string, email string, domain string)
- func GenerateVaultDeviceID() string
- func GetClient(ctx context.Context) (*oauth2.Config, error)
- func ImportCalendar(database *sql.DB, client *calendar.Service, initial bool) error
- func ImportContacts(database *sql.DB, client *people.Service) error
- func ImportGmail(database *sql.DB, client *gmail.Service, initial bool) error
- func IsHighSignalEmail(message *gmail.Message, userEmail string) (bool, string)
- func LoadToken() (*oauth2.Token, error)
- func NewCalendarClient(token *oauth2.Token) (*calendar.Service, error)
- func NewGmailClient(token *oauth2.Token) (*gmail.Service, error)
- func NewOAuthConfig() *oauth2.Config
- func NewPeopleClient(token *oauth2.Token) (*people.Service, error)
- func SaveToken(token *oauth2.Token) error
- func SaveVaultConfig(cfg *VaultConfig) error
- func TokenPath() string
- func VaultConfigDir() string
- func VaultConfigPath() string
- type CompanyPayload
- type ContactCadencePayload
- type ContactMatcher
- type ContactPayload
- type ContactsImporter
- type DealNotePayload
- type DealPayload
- type GoogleContact
- type InteractionLogPayload
- type RelationshipPayload
- type SuggestionPayload
- type VaultConfig
- type VaultSyncer
- func (s *VaultSyncer) Close() error
- func (s *VaultSyncer) LastSyncedSeq(ctx context.Context) (int64, error)
- func (s *VaultSyncer) PendingChanges(ctx context.Context) ([]vault.OutboxItem, error)
- func (s *VaultSyncer) PendingCount(ctx context.Context) (int, error)
- func (s *VaultSyncer) QueueCompanyChange(ctx context.Context, company *models.Company, op vault.Op) error
- func (s *VaultSyncer) QueueContactCadenceChange(ctx context.Context, cadence *models.ContactCadence, contactName string, ...) error
- func (s *VaultSyncer) QueueContactChange(ctx context.Context, contact *models.Contact, companyName string, op vault.Op) error
- func (s *VaultSyncer) QueueDealChange(ctx context.Context, deal *models.Deal, companyName, contactName string, ...) error
- func (s *VaultSyncer) QueueDealNoteChange(ctx context.Context, note *models.DealNote, dealTitle string, op vault.Op) error
- func (s *VaultSyncer) QueueInteractionLogChange(ctx context.Context, interaction *models.InteractionLog, contactName string, ...) error
- func (s *VaultSyncer) QueueRelationshipChange(ctx context.Context, rel *models.Relationship, ...) error
- func (s *VaultSyncer) QueueSuggestionChange(ctx context.Context, suggestion *models.Suggestion, op vault.Op) error
- func (s *VaultSyncer) Sync(ctx context.Context) error
- func (s *VaultSyncer) SyncWithEvents(ctx context.Context, events vault.SyncEvents) error
Constants ¶
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.
const AppID = "e9240d3f-967d-485e-8c63-e0adf7eecca0"
AppID is the namespace UUID for pagen sync data.
Variables ¶
This section is empty.
Functions ¶
func BuildHighSignalQuery ¶
BuildHighSignalQuery builds a Gmail API query for high-signal emails only.
func ExtractEmailAddress ¶
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 ImportCalendar ¶
ImportCalendar fetches and imports calendar events from Google Calendar.
func ImportContacts ¶
ImportContacts fetches and imports contacts from Google People API.
func ImportGmail ¶
ImportGmail fetches and imports high-signal emails from Gmail.
func IsHighSignalEmail ¶
IsHighSignalEmail checks if an email meets high-signal criteria.
func NewCalendarClient ¶
NewCalendarClient creates a Google Calendar API service from an OAuth token.
func NewGmailClient ¶
NewGmailClient creates a new Google Gmail API client.
func NewOAuthConfig ¶
NewOAuthConfig creates OAuth2 config for Google APIs.
func NewPeopleClient ¶
NewPeopleClient creates a new Google People API client.
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.
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 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.