---
title: CallRex WCF proxy operations
summary: Wraps the third-party CallRex ClientService and AgentStateService WCF endpoints for recording retrieval/control and real-time agent call-state monitoring.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-09-15
library: SAIF.Application.Services.AudioVideo.32
reference_type: package
operation_id: OP-AV-CALLREX-PROXY
trigger: Invoked internally by CallRecordingSystem on behalf of AudioVideoService and other IRecordingSystem consumers
---

# CallRex WCF proxy operations

`CallRecordingSystem` (the sole `IRecordingSystem` implementation) composes two WCF client wrappers — `CallRexServiceProxy` and `CallRexStateServiceProxy` — that talk to the third-party CallRex call-recording system's `ClientService` and `AgentStateService` endpoints. This page documents both proxies as one cross-cutting integration operation because they are always used together by `CallRecordingSystem` and share the same authentication pattern.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-AV-CALLREX-PROXY |
| **Trigger** | Any `IRecordingSystem` member call routed through `CallRecordingSystem` (`GetRecording`, `GetRecordings`, `GetCallUsers`, `GetAllUsersCurrentCallState`, `GetCallUser`, `MarkInvalid`, `DeleteRecording`, `StartRecording`, `StopRecording`, `PauseRecording`, `ResumeRecording`, `StartMonitoring`, `StopMonitoring`) |
| **Inputs** | Varies by member: `Guid` recording/user identifiers, `CallUser`, `RealtimeUserState` (from the agent-state callback) |
| **Outputs** | `CallRecording`/`CallUser` collections, `bool` success flags, and `CallMonitorState` events raised through `OnCallStateChanged` |
| **Primary components** | `CallRecordingSystem`, `CallRexServiceProxy`, `CallRexStateServiceProxy`, `AgentStateCallback` |
| **Entry point** | `Application\SAIF.Application.Services.AudioVideo\Services\Utilities\AudioVideo\RecordingSystem.cs` |

## Steps

1. `CallRexServiceProxy` wraps `Core.ThirdParty.CallRex.ClientServiceClient` (WCF, endpoint address resolved at runtime from `AudioImportService.callRexServiceUrl`; design-time `app.config` address is `http://localhost:8002/ClientService`, SPN identity `qmssvc@corp.saif.com`).
   - On construction, eagerly calls `_webService.Login("AI", "AudioImporter")` — a hard-coded service-account credential pair.
2. All state-changing calls (`MarkInvalid`, `DeleteRecording`, `StartRecording`, `StopRecording`, `PauseRecording`, `ResumeRecording`) are wrapped in `AuthorizeClientServiceCall`, which adds custom SOAP headers `Username`/`Password` (same hard-coded credentials) to every outgoing message via `OperationContextScope`.
3. `CallRexStateServiceProxy` wraps `Core.ThirdParty.CallRexAgentState.AgentStateServiceClient` (dual/duplex WCF binding, endpoint resolved at runtime from `AudioImportService.callRexStateServiceUrl`; design-time `app.config` addresses are `net.tcp://localhost:8015/AgentStateService` or `http://localhost:8003/AgentStateService2`).
4. `CallRexStateServiceProxy` pushes real-time agent call-state callbacks through `AgentStateCallback.ReceiveState`, which converts the incoming `RealtimeUserState` and raises `CallStateChanged`.
5. `CallRecordingSystem.CallState_Changed` handles that delegate and re-raises it as the `OnCallStateChanged` event exposed to `CallRecordingSystem` callers.
6. `CallRecordingSystem.GetRecordings(string userId)` resolves a `CallUser` first via `GetCallUser` (case-insensitive `UserId` match), then delegates to `GetRecordings(CallUser)` — a two-step lookup rather than a single direct query.

## Process flow

The following diagram visualizes the recording-control and agent-state-monitoring call paths.

```mermaid
flowchart TD
	Consumer[AudioVideoService / IRecordingSystem consumer] --> RS[CallRecordingSystem]
	RS -->|Recording retrieval/control| Proxy1[CallRexServiceProxy]
	Proxy1 -->|Login once, auth header per call| ClientService["CallRex ClientService (WCF)"]
	RS -->|Agent-state monitoring| Proxy2[CallRexStateServiceProxy]
	Proxy2 -->|Duplex/callback| AgentStateService["CallRex AgentStateService (WCF)"]
	AgentStateService -.->|RealtimeUserState| Callback[AgentStateCallback]
	Callback --> RS
	RS -->|OnCallStateChanged| Consumer
```

## Failure and edge-case behavior
- A failed `Login` at `CallRexServiceProxy` construction leaves the proxy unable to authorize any subsequent state-changing call.
- `GetRecordings(string userId)` returns no recordings if `GetCallUser` cannot resolve a matching `CallUser` for the given `userId`.
- The hard-coded CallRex credentials (`"AI"` / `"AudioImporter"`) are compiled directly into `CallRexServiceProxy` rather than retrieved via `IEnvironmentService.GetSecureConfigSetting` — see [Configuration](../configuration.md) for the associated configuration/secrets-management risk.

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)

## Sources
- `Application\SAIF.Application.Services.AudioVideo\Services\Utilities\AudioVideo\RecordingSystem.cs`
- `Application\SAIF.Application.Services.AudioVideo\Services\ClientProxies\ThirdParty\CallRexServiceProxy.cs`
- `Application\SAIF.Application.Services.AudioVideo\Services\ClientProxies\ThirdParty\CallRexStateServiceProxy.cs`
- `Application\SAIF.Application.Services.AudioVideo\Services\ClientProxies\ThirdParty\AgentStateCallback.cs`
- `Application\SAIF.Application.Services.AudioVideo.32\app.config`
