contacts: caller names on desk phones while they ring (C4)
ci / check (push) Successful in 1m2s
ci / images (push) Successful in 22s

Spec 11 §6.1: sp-sub-dial-user asks /api/internal/caller-name (func_curl, 2 s at most; this
machine only, with an APP_SECRET-derived key, not logged) for the ringing user's name for the
caller, and sets it on each ringing leg (pre-dial handler, CONNECTEDLINE), never on the call, so
forwards and other members don't see someone else's contacts. Ring group/queue/number prefixes
kept. Contrack lookups never wait (cache, contactsWarm every 5 min). Proven on real Asterisk
with baresip: apps/api/test/asterisk/cnam-test.ts.
This commit is contained in:
iamdoubz committed 2026-10-23 15:45:36 -05:00
1 parent 692dd59552
commit b05361e840
51 files changed
+1040 -31

No files matched your search

+23 -1
View File
@@ -12,16 +12,38 @@ exten => s,1,Set(N=\${FILTER(0123456789+,\${ARG1})})
; ─── Ring every registered device of a user. ARG1 = ext, ARG2 = seconds.
; Sets DIALSTATUS. Rings desk/softphone contacts (PJSIP/101) and browser (PJSIP/101-web).
; A call from outside shows the caller's name from this user's contacts (11 §6 C4): set on each
; ringing leg only (sp-predial-cnam), never on the call itself, so a forward or the next member
; never sees someone else's contact name.
[sp-sub-dial-user]
exten => s,1,Set(DS=)
same => n,Gosub(sp-sub-contacts,s,1(\${ARG1}))
same => n,Gosub(sp-sub-contacts,s,1(\${ARG1}-web))
same => n,GotoIf($["\${DS}" = ""]?unavail)
same => n,Dial(\${DS},\${ARG2},tx)
same => n,GotoIf($["\${SP_DIRECTION}" != "inbound" | "\${SP_CNAM_URL}" = ""]?plain)
same => n,Gosub(sp-sub-cnam,s,1(\${ARG1}))
same => n,GotoIf($["\${GOSUB_RETVAL}" = ""]?plain)
same => n,Set(_SP_CNAM=\${SP_CNAM_PREFIX}\${GOSUB_RETVAL})
same => n,Dial(\${DS},\${ARG2},txb(sp-predial-cnam^s^1))
same => n,Set(_SP_CNAM=)
same => n,Return()
same => n(plain),Dial(\${DS},\${ARG2},tx)
same => n,Return()
same => n(unavail),Set(DIALSTATUS=CHANUNAVAIL)
same => n,Return()
; ─── The caller's name in user ARG1's contacts, or "" (none, or the api didn't answer in 2 s).
; The api only answers this machine with the key, and only letters, digits and . ' & @ - come back.
[sp-sub-cnam]
exten => s,1,Set(CURLOPT(conntimeout)=1)
same => n,Set(CURLOPT(httptimeout)=2)
same => n,Return(\${CURL(\${SP_CNAM_URL}?ext=\${FILTER(0-9,\${ARG1})}&number=\${FILTER(0-9,\${CALLERID(num)})}&token=\${SP_CNAM_TOKEN})})
; ─── Pre-dial handler on each ringing leg: the name its phone shows.
[sp-predial-cnam]
exten => s,1,Set(CONNECTEDLINE(name,i)=\${SP_CNAM})
same => n,Return()
; ─── Add AOR ARG1's reachable contacts to DS as PJSIP/<ARG1>/<uri>. Not PJSIP_DIAL_CONTACTS: iOS
; Linphone's push params (pn-prid=…:voip&…:remote) hold '&', which splits Dial's device list.
; pn-* only matter to a push server, so they're dropped; FILTER keeps whatever else a phone puts