Kommo CRM Integration — Clarin CRM
Architecture
Kommo integration is a one-way sync (Kommo → Clarin) using the Kommo REST API v4.
code
backend/internal/kommo/ client.go → Rate-limited HTTP client for Kommo API sync.go → SyncService: background worker (5s polling)
Sync Flow
- •
SyncService.Start()launches a goroutine that polls every 5 seconds - •Fetches leads, contacts, tags from Kommo API
- •Upserts into PostgreSQL via
repository.go - •Broadcasts
lead_updatevia WebSocket after sync
Key Components
client.go — Kommo API Client
- •Rate-limited (respects Kommo's API limits)
- •
GetLeads()— Fetches leads with pagination - •
GetContacts()— Fetches contacts with pagination - •
GetTags()— Fetches ALL tags with full pagination (fixed: was only page 1) - •Auth via Bearer token from environment variable
sync.go — Sync Service
- •
SyncServicestruct withclient,repo,db,hub - •
upsertLead()→ creates/updates lead, callssyncLeadTags() - •
upsertContact()→ creates/updates contact, callssyncContactTags() - •
syncLeadTags()→ populateslead_tagsjunction table - •
syncContactTags()→ populatescontact_tagsjunction table - •
NormalizePhone()→ Exported function for phone normalization
Phone Normalization
go
// Peru (51) is the only country supported
// 9-digit numbers starting with 9 get "51" prefix automatically
normalized := kommo.NormalizePhone("987654321") // → "51987654321"
normalized := kommo.NormalizePhone("51987654321") // → "51987654321" (unchanged)
ALWAYS use kommo.NormalizePhone() when handling phone numbers in:
- •
api/server.go→handleCreateLead() - •
service/service.go→CreateNewChat() - •
kommo/sync.go→ all sync operations
Adding New Synced Fields
- •Add field to Kommo API response struct
- •Add field to domain entity in
domain/entities.go - •Add migration in
database.go - •Update
upsertLead()orupsertContact()insync.go - •Update repository queries
- •Build, deploy, verify sync in logs