Voicemail uploads name their message, and Kamo can ask for one it has no audio of
A voicemail upload now carries the message's own id, <mailbox>/<msg_id> from the msgNNNN.txt Asterisk writes beside it, as its unique id: VOIPService files Free...
Render the toll-fraud block list as [kamo-toll-fraud-blocked] (SP93 T8)
The PBX policy pull now carries blockedPatterns, the Asterisk extension patterns of the phone server's optional toll-fraud guards. Fetch keeps only an underscor...
The AI endpoint writer does nothing until FreePBX has generated its endpoint file
Without pjsip.endpoint.conf nothing is known about which extensions exist, so Apply wrote empty managed AI sections (and reloaded), which would take every AI ex...
Why allow= alone keeps G.722 out of the offer to LiveKit
Review 1 asked whether codec_prefs_outgoing_offer (prefer:pending, operation:union) could still put a caller's g722 into Asterisk's offer to LiveKit. It cannot:...
AI extensions offer G.711 only, so the AI leg is never G.722
livekit-sip answers an offer with the codec it ranks highest, not the first one offered (media-sdk sdp.SelectAudio: G722 -5 > PCMU -10 > PCMA -20). With allow=!...
An AI extension's AOR block adds to the AOR, not to the endpoint of the same name
FreePBX names an extension's endpoint and its AOR alike, and pjsip.conf includes pjsip.endpoint.conf before pjsip.aor.conf. A bare [7900](+) in pjsip.aor_custom...
Pull the PBX policy from Kamo; outbound allow-list and AI extensions as managed dial plan; AI endpoints point at LiveKit
Every POLICY_SECONDS the agent pulls GET /api/voip/pbx/config (also its heartbeat) and writes [kamo-outbound-allowed] and [kamo-ai-extensions] as a managed sect...
One recording subroutine; file names keep the call's UNIQUEID; AMI reads call events
[kamo-record] now does the recording for every path: the trunk and voicemail predial hooks here call it, and so will the attendant, direct, agent, internal and ...
A rebuild of the same commit deployed nothing and reported success
The image is tagged with the commit SHA, so rebuilding the same commit produces an identical image reference. `kubectl set image` then changes nothing, the Depl...
Report ringing extensions so a member's mobile rings
The AMI client logs in with 'Events: off' and only sends actions, so nothing on a customer's FreePBX ever told the platform a call was arriving. That silence is...
Pin direct_media=no, and correct the "(+) cannot override" claim
FreePBX's PJSip driver defaults direct_media to YES (generateDefaultDeviceSettings, PJSip.class.php:210) and the GraphQL addExtension mutation has no field to o...
Reconcile per-extension WebRTC blocks instead of hand-editing a roster
An extension created through FreePBX's API gets no WebRTC block, so it registers over WSS and then has no DTLS or ICE β the browser softphone shows a connected ...
Predial hooks must Return(), not MacroExit() β Asterisk 21
Asterisk 21 removed the Macro() application family outright, and FreePBX reaches these hooks with Gosub() (extensions_additional.conf: **************** The stoc...
Harden the kubectl download against flaky egress [skip ci]
dl.k8s.io over the runner's egress intermittently drops mid-transfer: curl: (56) OpenSSL SSL_read: decryption failed or bad record mac which fails the deploy ...
Use k1m1 registry/API 192.168.4.22 (drop deprecated WireGuard IPs)
Drop offline-k2m1 deploy job + orphaned k2m1 manifests
Service ran on a stale cached k0m1:5000 image, never re-pushed to the k1m1 registry after k0m1 retirement; disk-pressure eviction wiped the cache (ImagePullBack...
Scope concurrency to build jobs, not Kubernetes deploys
Workflow-level concurrency serialized the whole pipeline (including kubectl rollouts). Move the group to the build job only so deploy jobs from different runs c...
Add go-sql-driver/mysql v1.7.1 checksum to go.sum
go mod tidy without source files is a no-op, so the mysql checksum was never added. Generated the correct h1 hashes via a throwaway golang:1.22-alpine container...
Move ASTERISK_CDR_DSN to local config.json, not CI/CD secrets
CDR credentials are local to each FreePBX server and have no business in the CI/CD pipeline. Operators add ASTERISK_CDR_DSN directly to their config.json alongs...
Enrich upload manifests with Asterisk CDR caller-ID data
Adds optional MySQL CDR enrichment so the softphone history tab can display who called (or was called). When ASTERISK_CDR_DSN is configured as a Forgejo repo se...
Emit recordedAt + per-file extension in upload manifest
- Watcher: every emitted Recording carries RecordedAt, derived from the EPOCH segment of our managed **************** filename, falling back to file mtime f...
Drop the [from-internal-custom] _X. catch-all that broke softphone calls
The catch-all exten => _X.,1 in [from-internal-custom] was intercepting every internal dial β softphones started reporting "phone is not registered" / calls wou...
Write managed config files 0644 so the asterisk daemon can read them
The kamo-asterisk-support pod runs as root and writes to host-mounted **************** Asterisk inside the FreePBX pod runs as user "asterisk" and could not rea...
Use envsubst-compatible \${VAR} syntax in config template + re-render on stale placeholders
Pods were CrashLoopBackOff with "config errors: API_KEY is missing or too short" because the config template used literal __API_KEY__ markers that envsubst sile...
Drop unused watcher import
uploader.go only uses CallBatch (declared in grouper.go in the same package), not anything from internal/watcher directly. Go rejects unused imports.
Initial commit β FreePBX recording uploader (GO)
Watches **************** for finished WAV recordings, groups multi-leg call legs by Asterisk UNIQUEID, and uploads each batch to APIService /api/voip/recordings...
Initial commit β FreePBX recording uploader (GO)
Watches **************** for finished WAV recordings, groups multi-leg call legs by Asterisk UNIQUEID, and uploads each batch to APIService /api/voip/recordings...
Like what you see shipping?
All of it arrives in your workspace on its own. Start on the free plan and read this page again in a month.
