Files
claudetools/clients/valleywide/voip/COMPLETE-CLIENT-SETUP.md
Mike Swanson db10206aea feat(voip): VWP complete provisioning prep + setup documentation
Critical RPS provisioning URL fix + CSV bulk import ready + complete VoIP setup guide

CRITICAL FIX:
- RPS server URL corrected: http://ndp.ucaasnetwork.com/cfg (was ftp://p.packetdials.net)
- Discovered ACG has TWO whitelabel accounts (WLC vs OIT/PacketDial)
- Test phone (805e0cdd71b1) now registered immediately after fix (Status 1)

USER PROVISIONING:
- M365 account matching: 11 matched users, 7 unmatched (need clarification)
- CSV bulk import prepared (vwp-users-import.csv)
- Strategy: users WITHOUT devices initially (add phone extension: no)
- Device assignment workflow: incremental as phones distributed

COMPLETE VOIP SETUP DOCUMENTED:
- DID (phone number) management + routing options
- Call queues (ring groups) - recommended queues for VWP
- Auto-attendants (IVR menus) - main menu design
- Time frames (business hours routing)
- Additional features (hunt groups, voicemail-only, fax-to-email)
- All components with API commands + examples

FILES CREATED (7):
- README.md: Quick navigation hub + domain info
- PROVISIONING-STATUS.md: Current status + next steps
- SESSION-SUMMARY-2026-07-09.md: Complete session documentation (18 pages)
- COMPLETE-CLIENT-SETUP.md: Full VoIP setup guide (15 pages)
- DEVICE-ASSIGNMENT-COMMANDS.md: Copy-paste command reference
- extension-mapping.md: Extension to M365 account mapping
- vwp-users-import.csv: Bulk import file (READY for upload)

IMPLEMENTATION PHASES:
Phase 1 (In Progress): Basic connectivity - CSV ready for upload
Phase 2 (Planned): Main line setup - queue + auto-attendant + DID
Phase 3 (Planned): Business hours routing - time-based call handling
Phase 4 (Optional): Additional features per client needs

NEXT ACTIONS:
- Upload CSV to PacketDial web UI (manual step)
- Get client clarification on 7 unmatched users
- Assign devices as phones distributed (per-phone workflow documented)

Domain: vwp.91912.service
Main Number: 480-705-9500
E911: a-6a395c03d4cfe (301 N 56TH ST, CHANDLER AZ)
YMCS Site: 1e7578a6fe0e41cfb5a3e8b40933ffee

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-07-09 20:21:57 -07:00

608 lines
16 KiB
Markdown

# Complete VoIP Client Setup - PacketDial/NetSapiens
**Client:** Valley Wide Plastering
**Domain:** vwp.91912.service
**Date:** 2026-07-09
---
## Overview
Setting up a complete VoIP client involves more than just users and phones. This document explores all elements needed for a production-ready VoIP deployment.
## Current VWP Status
Based on live API queries (2026-07-09):
```
Domain: vwp.91912.service
Users: 2 configured (needs 11 more from CSV)
DIDs: 0 (no phone numbers assigned)
Call Queues: 0 (no ring groups)
Auto-Attendants: 0 (no IVR menus)
Time Frames: 0 (no business hours routing)
Sites: 0 (single-site default)
```
---
## 1. Phone Number (DID) Management
### What DIDs Are
DIDs (Direct Inward Dialing) are phone numbers that route inbound calls to your PBX. Each DID needs routing rules to determine where calls go.
### DID Routing Applications
PacketDial supports multiple routing methods via `dial-rule-application`:
| Application | Routes To | Use Case |
|-------------|-----------|----------|
| `to-user` | Specific extension | Direct line to one person |
| `to-user-residential` | User with residential features | Home/mobile integration |
| `to-queue` | Call queue (ring group) | Sales, support, general line |
| `to-attendant` | Auto-attendant (IVR) | Main company line with menu |
| `to-voicemail` | Voicemail box | After-hours voicemail-only line |
| `to-hunt-group` | Hunt group | Sequential/round-robin routing |
### Example: ACG Domain DIDs
From `arizonacomputerguru` domain:
```json
{
"phonenumber": "15202651226",
"dial-rule-application": "to-user",
"dial-rule-translation-destination-user": "15202651226",
"dial-rule-description": "Main office line - routes to extension 1226"
}
```
### VWP DID Strategy
**Main Number:** 480-705-9500 (from wiki)
**Recommended Initial Setup:**
1. Create main DID → routes to auto-attendant (IVR menu)
2. Auto-attendant options:
- Press 0 → receptionist (or general queue)
- Press 1 → sales queue
- Press 2 → accounting/payroll
- Direct dial by extension (1-0-2 for extension 102)
**API Command to Create DID:**
```bash
# Option 1: Route to specific user (direct line)
ns.py create-did vwp.91912.service --body '{
"phonenumber": "14807059500",
"dial-rule-application": "to-user",
"dial-rule-translation-destination-user": "102",
"dial-rule-description": "Main line - Jesse Guerrero"
}' --confirm
# Option 2: Route to call queue (recommended for main line)
ns.py create-did vwp.91912.service --body '{
"phonenumber": "14807059500",
"dial-rule-application": "to-queue",
"dial-rule-parameter": "8000",
"dial-rule-description": "Main line - General queue"
}' --confirm
# Option 3: Route to auto-attendant (best for main line)
ns.py create-did vwp.91912.service --body '{
"phonenumber": "14807059500",
"dial-rule-application": "to-attendant",
"dial-rule-parameter": "3000",
"dial-rule-description": "Main line - IVR menu"
}' --confirm
```
---
## 2. Call Queues (Ring Groups)
### What They Are
Call queues ring multiple phones simultaneously or in sequence until someone answers. Essential for:
- Reception/front desk
- Sales teams
- Support teams
- After-hours coverage
### Call Queue Features
- **Dispatch Types:**
- `Ring-all` (simultaneous) - all phones ring at once
- `Round-robin` - distributes calls evenly
- `Top-down` - tries agents in order
- `Longest-idle` - routes to agent idle longest
- **Queue Music:** Plays music while callers wait
- **Position Announcements:** "You are caller number 3"
- **Overflow:** Route to voicemail after X rings or Y minutes
- **Agent Login/Logout:** Agents can log in/out of queue
### Creating a Call Queue
**Example: General Reception Queue**
```bash
# Step 1: Create the queue
ns.py create-callqueue vwp.91912.service --body '{
"synchronous": "yes",
"callqueue": "8000",
"description": "General Reception",
"callqueue-dispatch-type": "Ring-all",
"callqueue-max-wait-time": 300,
"callqueue-no-answer-destination": "voicemail:8000@vwp.91912.service"
}' --confirm
# Step 2: Add agents (users who will receive calls)
ns.py add-agent vwp.91912.service 8000 --body '{
"callqueue-agent-id": "102@vwp.91912.service",
"callqueue-agent-dispatch-order-ordinal": 1
}' --confirm
ns.py add-agent vwp.91912.service 8000 --body '{
"callqueue-agent-id": "103@vwp.91912.service",
"callqueue-agent-dispatch-order-ordinal": 2
}' --confirm
```
### VWP Queue Recommendations
Based on the 18 extensions provided:
1. **Queue 8000 - General/Reception**
- Agents: Jesse (102), Rose (103), Shelly (104)
- Dispatch: Ring-all
- Purpose: Main company line
2. **Queue 8001 - Management**
- Agents: Jesse (102), J.R. (105), Chris (113)
- Dispatch: Top-down
- Purpose: Escalated calls
3. **Queue 8002 - Accounting/Payroll**
- Agents: Payroll (107), Toni (115)
- Dispatch: Ring-all
- Purpose: Billing inquiries
---
## 3. Auto-Attendants (IVR Menus)
### What They Are
Interactive Voice Response (IVR) menus that greet callers and route based on keypress:
- "Press 1 for Sales, Press 2 for Support, Press 0 for Operator"
### Auto-Attendant Structure
Components:
1. **Greeting Prompt:** Audio message callers hear
2. **Menu Options:** Keypresses (0-9, *, #)
3. **Destinations:** Where each option routes (user, queue, voicemail, sub-menu)
4. **Timeout Action:** What happens if caller doesn't press anything
5. **Invalid Action:** What happens on invalid keypress
### Creating an Auto-Attendant
```bash
# Create basic auto-attendant
ns.py create-autoattendant vwp.91912.service --body '{
"synchronous": "yes",
"user": "3000",
"attendant-name": "Main Menu",
"attendant-greeting-prompt": "Welcome to Valley Wide Plastering. Press 1 for Sales, Press 2 for Accounting, or stay on the line for our receptionist.",
"attendant-timeout-seconds": 10,
"attendant-timeout-destination": "queue:8000@vwp.91912.service"
}' --confirm
```
**Note:** The greeting prompt can be:
- Text (uses TTS - text-to-speech)
- Uploaded audio file (.wav)
- Professionally recorded message
### Menu Option Configuration
After creating the auto-attendant, add menu options:
```bash
# Option 1: Route to queue
ns.py raw POST domains/vwp.91912.service/autoattendants/3000/options --body '{
"key": "1",
"destination": "queue:8001@vwp.91912.service",
"description": "Sales"
}' --confirm
# Option 2: Route to specific extension
ns.py raw POST domains/vwp.91912.service/autoattendants/3000/options --body '{
"key": "2",
"destination": "user:107@vwp.91912.service",
"description": "Payroll"
}' --confirm
# Option 0: Operator
ns.py raw POST domains/vwp.91912.service/autoattendants/3000/options --body '{
"key": "0",
"destination": "queue:8000@vwp.91912.service",
"description": "Receptionist"
}' --confirm
```
---
## 4. Time Frames (Business Hours Routing)
### What They Are
Time-based routing rules that change call handling based on:
- Day of week (Monday-Friday vs weekend)
- Time of day (business hours vs after-hours)
- Specific dates (holidays, company events)
### Time Frame Types
| Type | Use Case |
|------|----------|
| `always` | Always active (default) |
| `days-of-week` | M-F 8am-5pm, etc. |
| `specific-dates` | Dec 25, Jan 1, company holidays |
| `holiday` | Follows holiday calendar |
| `custom` | Complex logic |
### Creating Business Hours
```bash
# Step 1: Create business hours timeframe
ns.py create-timeframe vwp.91912.service --body '{
"synchronous": "yes",
"timeframe-name": "Business Hours",
"timeframe-type": "days-of-week",
"timeframe-days-of-week-array": [
{
"day-of-week": "monday",
"start-time": "08:00:00",
"end-time": "17:00:00"
},
{
"day-of-week": "tuesday",
"start-time": "08:00:00",
"end-time": "17:00:00"
},
{
"day-of-week": "wednesday",
"start-time": "08:00:00",
"end-time": "17:00:00"
},
{
"day-of-week": "thursday",
"start-time": "08:00:00",
"end-time": "17:00:00"
},
{
"day-of-week": "friday",
"start-time": "08:00:00",
"end-time": "17:00:00"
}
]
}' --confirm
# Step 2: Create after-hours timeframe
ns.py create-timeframe vwp.91912.service --body '{
"synchronous": "yes",
"timeframe-name": "After Hours",
"timeframe-type": "always"
}' --confirm
```
### Using Time Frames with DIDs
Modify DID routing based on time:
```bash
# Update DID to use time-based routing
ns.py update-did vwp.91912.service 14807059500 --body '{
"dial-rule-matching-timeframe": "{timeframe-id-business-hours}",
"dial-rule-application": "to-attendant",
"dial-rule-parameter": "3000"
}' --confirm
```
**After-Hours DID Rule:**
```bash
# Create second rule for same DID (after-hours)
ns.py create-did vwp.91912.service --body '{
"phonenumber": "14807059500",
"dial-rule-matching-timeframe": "{timeframe-id-after-hours}",
"dial-rule-application": "to-voicemail",
"dial-rule-parameter": "8000",
"dial-rule-description": "After hours - main voicemail"
}' --confirm
```
---
## 5. Other Client Setup Elements
### Sites (Multi-Location)
For clients with multiple physical locations:
```bash
ns.py create-site vwp.91912.service --body '{
"site": "Chandler-Main",
"site-description": "Main Office - 301 N 56th St",
"site-address-line-1": "301 N 56TH ST",
"site-address-city": "CHANDLER",
"site-address-state-province-abbreviation": "AZ",
"site-address-postal-code": "85226"
}' --confirm
```
**Use Case:** Different caller ID, different local area code, site-to-site dialing
### Hunt Groups
Similar to queues but with sequential routing:
```bash
# Ring extension 102, if no answer try 103, then 104
ns.py create-huntgroup vwp.91912.service --body '{
"huntgroup": "9000",
"description": "Management Hunt",
"huntgroup-type": "sequential",
"huntgroup-members": ["102", "103", "104"],
"huntgroup-timeout": 20
}' --confirm
```
### Voicemail-Only Numbers
For departments without dedicated phones:
```bash
ns.py create-user vwp.91912.service --body '{
"user": "9999",
"name-first-name": "Warehouse",
"name-last-name": "Voicemail",
"email": "warehouse@valleywideplastering.com",
"emergency-address-id": "a-6a395c03d4cfe"
}' --confirm
# Route DID directly to voicemail (no ringing)
ns.py create-did vwp.91912.service --body '{
"phonenumber": "14807059501",
"dial-rule-application": "to-voicemail",
"dial-rule-parameter": "9999",
"dial-rule-description": "Warehouse messages"
}' --confirm
```
### Fax to Email
Enable fax reception (routes faxes to email as PDF):
```bash
ns.py create-faxaccount vwp.91912.service --body '{
"user": "8888",
"email": "faxes@valleywideplastering.com",
"description": "Main fax line"
}' --confirm
# Assign DID to fax
ns.py create-did vwp.91912.service --body '{
"phonenumber": "14807059502",
"dial-rule-application": "to-fax",
"dial-rule-parameter": "8888",
"dial-rule-description": "Fax line"
}' --confirm
```
---
## 6. Recommended VWP Setup Plan
### Phase 1: Basic Connectivity (DONE/IN PROGRESS)
- [x] Domain created
- [x] E911 address configured
- [x] 11 matched users ready for CSV import
- [ ] Users created in PacketDial
- [ ] Devices assigned as phones distributed
### Phase 2: Main Line Setup (NEXT)
1. **Create General Reception Queue (8000)**
- Agents: Jesse (102), Rose (103), Shelly (104)
- Dispatch: Ring-all
- Max wait: 60 seconds → voicemail
2. **Create Main Auto-Attendant (3000)**
- Greeting: "Thank you for calling Valley Wide Plastering..."
- Option 0: Reception queue (8000)
- Option 1: Sales/Estimating - Bart (116)
- Option 2: Accounting/Payroll - Payroll dept (107)
- Timeout: Ring reception queue (8000)
3. **Assign Main DID**
- Number: 480-705-9500
- Route to: Auto-attendant (3000)
### Phase 3: Business Hours Routing
1. **Create Business Hours Time Frame**
- Monday-Friday, 7:00 AM - 5:00 PM (Arizona time)
2. **Create After-Hours Time Frame**
- All other times
3. **Update Main DID Routing**
- Business hours: Auto-attendant (3000)
- After hours: General voicemail (8000)
### Phase 4: Additional Features
1. **Department Queues**
- Management queue (8001)
- Accounting queue (8002)
2. **Shared Extensions**
- Kitchen (111) - physical phone
- Conference Room (112) - physical phone
- Warehouse (118) - voicemail only or physical phone
3. **Direct Lines (if needed)**
- Additional DIDs for key personnel
- Port existing numbers
---
## 7. Complete Setup Script Outline
### Inputs Needed
```json
{
"domain": "vwp.91912.service",
"main_did": "14807059500",
"business_hours": {
"start": "07:00:00",
"end": "17:00:00",
"days": ["monday", "tuesday", "wednesday", "thursday", "friday"],
"timezone": "America/Phoenix"
},
"queues": [
{
"id": "8000",
"name": "General Reception",
"agents": ["102", "103", "104"],
"dispatch": "Ring-all"
}
],
"auto_attendant": {
"id": "3000",
"greeting": "Thank you for calling Valley Wide Plastering. For reception, press 0. For estimating, press 1. For accounting, press 2.",
"options": [
{"key": "0", "destination": "queue:8000"},
{"key": "1", "destination": "user:116"},
{"key": "2", "destination": "user:107"}
],
"timeout_destination": "queue:8000"
}
}
```
### Execution Order
1. Verify users exist (from CSV import)
2. Create call queue(s)
3. Add agents to queue(s)
4. Create auto-attendant
5. Configure auto-attendant menu options
6. Create business hours timeframe
7. Create after-hours timeframe
8. Create main DID with business hours routing
9. Create after-hours DID rule
10. Test inbound calling
11. Verify voicemail delivery
---
## 8. Testing Checklist
### Inbound Call Testing
- [ ] Call main number during business hours → hears auto-attendant
- [ ] Press 0 → rings reception queue (multiple phones)
- [ ] Press 1 → rings estimating (ext 116)
- [ ] Press 2 → rings accounting (ext 107)
- [ ] Press invalid key → reprompts or routes to default
- [ ] Wait without pressing anything → routes to reception
- [ ] Call after hours → goes directly to voicemail
- [ ] Check voicemail email delivery
### Internal Calling
- [ ] Dial extension-to-extension (e.g., 102 calls 103)
- [ ] Dial queue extension (e.g., 102 dials 8000)
- [ ] Transfer calls between extensions
- [ ] Conference calling works
- [ ] Voicemail-to-email delivery
- [ ] Call park/pickup (if configured)
### Outbound Calling
- [ ] Extension dials external number (verify caller ID shows main number)
- [ ] Emergency calls (911) route correctly
- [ ] Long distance allowed per dial-policy
- [ ] International blocked (unless needed)
---
## 9. Next Steps for VWP
**Immediate (After CSV Import):**
1. Verify 11 users created successfully
2. Get client clarification on 7 unmatched extensions
3. Create general reception queue (8000)
4. Create main auto-attendant (3000)
5. Assign main DID (480-705-9500)
**Short-term:**
1. Set up business hours routing
2. Assign physical phones to users
3. Create additional queues as needed
4. Configure voicemail greetings
5. Test all call flows
**Optional/Future:**
1. Port additional phone numbers
2. Set up department-specific DIDs
3. Configure call recording (if needed)
4. Set up fax-to-email
5. Add reporting/analytics
---
## API Commands Reference
### DIDs
```bash
ns.py dids {domain} # List all DIDs
ns.py create-did {domain} --body '{...}' # Create DID
ns.py update-did {domain} {number} --body '{...}' # Update routing
ns.py delete-did {domain} {number} --confirm # Remove DID
```
### Call Queues
```bash
ns.py callqueues {domain} # List queues
ns.py create-callqueue {domain} --body '{...}' --confirm
ns.py add-agent {domain} {queue} --body '{...}' --confirm
ns.py remove-agent {domain} {queue} {agent} --confirm
ns.py delete-callqueue {domain} {queue} --confirm
```
### Auto-Attendants
```bash
ns.py autoattendants {domain} # List auto-attendants
ns.py create-autoattendant {domain} --body '{...}' --confirm
ns.py raw POST domains/{domain}/autoattendants/{id}/options --body '{...}'
```
### Time Frames
```bash
ns.py timeframes {domain} # List time frames
ns.py create-timeframe {domain} --body '{...}' --confirm
ns.py update-timeframe {domain} {id} --body '{...}' --confirm
ns.py delete-timeframe {domain} {id} --confirm
```
---
**Last Updated:** 2026-07-09
**Document Status:** Exploration / Planning
**Next Action:** Discuss with client which features are needed for go-live