Files
iamdoubz 604e40adf1
ci / check (push) Successful in 1m2s
ci / images (push) Successful in 20s
ci / check (pull_request) Successful in 1m4s
ci / images (pull_request) Successful in 5s
contacts: owners' contacts on their desk phones, copy builtin contacts to Contrack (C6)
Spec 11 §6.2: a phone's directory is the extensions, its owner's own contacts (accepted shares
included), then the company's, in both modes. In Contrack mode, contacts from before Contrack
are offered for copying (contrack.toCopy, POST …/copy-to-contrack: one Contrack bulk import,
skipping what's already there; the builtin rows stay). Tested against a fake and a real
Contrack 2.0.2.
2026-10-23 16:07:19 -05:00

5.3 KiB

Contacts

Contacts put names on numbers: in call history, voicemail, the browser phone and desk phones while they ring, the call report email, and the directory on desk phones (each phone has its owner's contacts and the company's). Pick where they live in the setup wizard or in Settings → Contacts:

  • Simple: a phonebook inside SelfPhoneNG. Nothing else to run.
  • Contrack: Contrack, a full contact and relationship manager, running next to the phone system as its own container.

Everyone has their own contacts, and there are company contacts that everyone sees (only admins change them, in Admin → Contacts).

Simple

  • My Phone → Contacts: add, edit, search, click a number to call. Calls and voicemails from a number that isn't a contact have Add to contacts.
  • Import: one or more .vcf files (exported from an iPhone, Android, Google Contacts, Outlook or Apple Contacts) or a CSV with a header row (name, company, email, label1, number1, label2, number2, …). You see what will be added first; contacts already there (same name and number) are skipped. Up to 5,000 contacts at a time.
  • Share: tick contacts, Share, pick colleagues or everyone. They get "Shared with you" at the top of their Contacts page and on Home, and choose Accept (a copy goes into their contacts) or Deny. Nothing is added to anyone's contacts without their click.

Contrack

Contrack keeps each person's contacts in their own private Contrack account, and the company's in a Contrack account of its own. SelfPhoneNG reads them (names on calls, the directory on desk phones), adds to them ("Add to contacts", accepted shares), and links to them. Editing, importing, notes and the rest happen in Contrack.

Set it up

  1. Give it a DNS name of its own, such as contacts.example.com (Contrack can't live under a path of the phone system's name), pointing at this server. Set it in .env:

    CONTRACK_HOSTNAME=contacts.example.com
    
  2. Start it:

    docker compose --env-file .env -f deploy/contrack/compose.yml up -d
    

    It listens on 127.0.0.1:3210 only.

  3. Put it behind your reverse proxy: with the bundled Caddy, uncomment the Contrack block at the end of deploy/caddy/Caddyfile and restart Caddy; with your own nginx, see the end of deploy/nginx/selfphoneng.conf.example.

  4. Open https://contacts.example.com. The first visit creates the first (admin) account. Then, in Contrack's Settings → Administration → Invitations, invite each person, and make one account for the company, such as company@example.com.

  5. Signed in to Contrack as the company account: Settings → Account → API tokens → Create token. Under Expires choose Never (or 1 year, and replace it before then): the default is 90 days, and names stop showing when a token expires. Read only is enough; Read and write lets admins add company contacts from SelfPhoneNG.

  6. In SelfPhoneNG, Settings → Contacts → Contrack: address http://127.0.0.1:3210, the address people open (https://contacts.example.com), the company token, Test, Save.

  7. Each person: in Contrack, Settings → Account → API tokens → Create token, Read and write, expiring Never (or 1 year), then in SelfPhoneNG My settings → Contacts, paste it, Connect. My settings says so when a token stops working.

Names refresh from Contrack every 5 minutes (at once after SelfPhoneNG adds a contact). If Contrack is down, the last names it gave keep working.

Calls on the timeline

Once connected, each person's calls with their Contrack contacts go on that contact's timeline in Contrack ("Incoming call", "Missed call, voicemail left", …, with the time on the phone and whether it was recorded), a minute or so after the call. In My settings → Contacts they can turn this off, or add each recorded call's summary and action items (when call summaries are on in Settings → AI); the first action item becomes a Contrack follow-up, due the next day. Calls with numbers that aren't in their Contrack aren't added; Add to contacts first. Only calls from the moment they connected are logged.

Privacy

SelfPhoneNG only talks to Contrack on this server or the local network, and keeps the tokens encrypted. Contrack itself can use AI (cloud providers, or your local Ollama) and look addresses up on OpenStreetMap: those are Contrack's settings, outside SelfPhoneNG's "nothing leaves the server" rule. To keep everything here, set AI_DISABLED and GEOCODING_DISABLED in deploy/contrack/compose.yml, or point Contrack's AI at your local AI in its Settings → Administration → AI.

Backups

SelfPhoneNG's backup doesn't include Contrack. Contrack makes its own snapshots in its contrack-data volume (its Settings → Backups); back up that volume too.

Moving to Contrack with contacts already in SelfPhoneNG

Switching from Simple keeps everyone's contacts. Each person (and an admin, for the company contacts) sees Copy them to Contrack on their Contacts page until they're copied; contacts Contrack already has are skipped.

Going back to Simple

Settings → Contacts → Simple. The builtin contacts are still there, and the Contrack tokens are kept in case you switch back.