voipms: API client, POP server list, import numbers

integrations/voipms/client.ts: voipmsApi(url, creds, method, params)
per 06 §5.1 (GET rest.php, 15 s timeout, status "success" or an error
code). The API password is only in the query string: never logged,
never in an error. Known codes get a message for people
(invalid_credentials, ip_not_enabled, ...). getServers and getDids
parse forgivingly; no_did is an empty list.

Routes: GET /api/trunks/:id/voipms-servers, GET and POST
/api/trunks/:id/import-dids. Import adds only numbers voip.ms lists
and that aren't added yet, label from the description, destination
hangup. 400 without API credentials, 502 provider_error with voip.ms's
reason. VOIPMS_API_URL overrides the endpoint for tests.

Web: the trunk form's server list comes from voip.ms once the trunk
has API access, falling back to the built-in list with the reason.
"Import numbers from voip.ms" sits in the trunk form's API section and
the setup wizard's numbers step. Saving a new API password asks
voip.ms again (found in e2e: the old error stayed).

The response shapes are from the 06 spec, not a real account: voip.ms's
API docs need a login. Marked TODO(spec) and (verify) in 06. Tests use
a fake rest.php; e2e m9-t1 too (trunk created off, so nothing registers
to the real voip.ms).

Task: M9-T1
This commit is contained in:
iamdoubz committed 2026-10-19 12:41:45 -05:00
1 parent 4742ed52ea
commit 33b1456c0f
13 files changed
+653 -7

No files matched your search

+1 -1
View File
@@ -373,7 +373,7 @@ Admin resources (all `requireAdmin`; standard CRUD = `GET /x`, `POST /x`, `GET /
|---|---|
| `/api/users` | `POST /:id/reset-password` (sets a temp password, `must_change_password`) |
| `/api/extensions` | `POST /:id/regenerate-sip-password`, `GET /:id/sip-credentials` (audited), `GET /:id/softphone-qr` (07 §5) |
| `/api/trunks` | `POST /:id/test` (live registration status + OPTIONS RTT), `POST /:id/import-dids` (voip.ms API, 06 §5) |
| `/api/trunks` | `POST /:id/test` (live registration status + OPTIONS RTT), `POST /:id/import-dids` (voip.ms API, 06 §5). As built (M9-T1): `GET /:id/voipms-servers` → `{servers: [hostname]}`; `GET /:id/import-dids` → the account's numbers `{number, description, smsEnabled, added}`; `POST /:id/import-dids {numbers}` adds only numbers voip.ms lists and that aren't added yet → `{added}`. 400 without API credentials on the trunk, 502 `provider_error` with voip.ms's reason (never the request URL). `VOIPMS_API_URL` overrides the endpoint for tests |
| `/api/dids` | |
| `/api/outbound-routes` | `POST /reorder {ids: []}`, `POST /test {extensionId, number}` → which route/trunk would be used, or why it's denied |
| `/api/ring-groups` | members are set via `members: [{extensionId}]` in POST/PATCH |
+7
View File
@@ -137,3 +137,10 @@ How SelfPhoneNG meets this:
## 7. DID import (`POST /api/trunks/:id/import-dids`)
Calls `getDIDsInfo`. Shows a list with checkboxes in the UI. Imported DIDs get
destination `{type:'hangup'}` and a warning chip "Not routed yet" until edited.
As built (M9-T1): `integrations/voipms/client.ts`. Assumed shapes (**verify** with a real account,
voip.ms's API docs need a login): `getServersInfo` → `servers[].server_hostname`; `getDIDsInfo` →
`dids[].did` (10 digits), `.description`, `.sms_enabled` ("1"); status `no_did` = no numbers;
`invalid_credentials`, `ip_not_enabled` get their own messages. "Import numbers from voip.ms" is in
the trunk form's API section and the setup wizard's numbers step; the label comes from the DID's
description. The server list falls back to the built-in one when the API can't be reached.