Skip to main content

ACS Module

Run automated phone calls on Azure Communication Services with TTS prompts and DTMF capture.

The ACS Module drives outbound and inbound voice calls through Azure Communication Services Call Automation. Each call step on the AcsPhone Channel starting the call, speaking a synthesized message, collecting a keypad digit, and hanging up is handled by this Module, so you can build IVR menus, outbound notifications, and voice surveys in the same BPMN editor you use for chat and Slack workflows. It requires Environment configuration: an Azure Communication Services connection and a linked Cognitive Services resource so prompts can be synthesized with Azure neural voices natively inside ACS. OpenAI / Resemble.ai streaming voices and a full conversational agent are rolling out over ACS bidirectional media streaming.

How it works

When a call is started or received on the AcsPhone Channel, the engine creates a Session and starts a Token through the Process. The live call stays bound to the Session for its entire lifetime, so every Task can address it.

At the Start Event the Module records the call details on the Session and writes the Module's Default Language into the Language Session variable so downstream Tasks pick it up. Each OutputTask converts its message to speech through the configured TTS provider and plays the audio over the call. Each InputTask speaks a prompt and then listens for a keypad (DTMF) digit the caller's digit is written into the configured variable when it arrives. At the End Event the Module hangs up the call.

If a Session ends abnormally before reaching the End Event, the Module automatically hangs up the dangling call so the Azure connection does not stay open and keep billing. No configuration is needed to enable this behavior.

Configuration

The ACS Module is configured per Environment each Environment supplies its own Azure Communication Services credentials and TTS settings. Set these values in the Module's Environment configuration. The settings are grouped the same way as the configuration form: Connection reaches Azure Communication Services, Text-to-Speech selects how prompts are synthesized, Media Streaming applies only to the streaming voice agent, and Voice Agent configures the optional conversational agent.

Connection

FieldTypeRequiredDescription
ACS Connection StringstringYesAzure Communication Services connection string (endpoint=https://...;accesskey=...). The single credential the Module uses to reach Azure.
Callback Base URLstringYesPublicly reachable base URL where Azure Communication Services delivers call event notifications (e.g. https://myapp.azurewebsites.net).
Default LanguagestringNoDefault language for call interactions when a Task doesn't override it. One of it-IT, en-US, en-GB, de-DE, fr-FR, es-ES. Default: it-IT.
Cognitive Services EndpointstringNoAzure AI / Cognitive Services endpoint linked to the ACS resource (e.g. https://myresource.cognitiveservices.azure.com). Required for the Azure voice path.
warning

The Module refuses to execute any Task until the ACS Connection String is set. While it is empty, every Task on the AcsPhone Channel stops with a configuration error and the call cannot proceed.

Text-to-Speech

FieldTypeRequiredDescription
TTS ProviderstringYesSpeech engine. Azure synthesizes neural voices natively inside ACS the supported path today. OpenAI / Resemble voices stream over the real-time media agent (rolling out). Default: Azure.

The settings for the selected provider appear below the TTS Provider field; the other providers' settings stay hidden.

Azure Speech settings shown when TTS Provider is Azure. The voice agent's speech recognition also uses this Speech resource.

FieldTypeRequiredDescription
Azure Speech EndpointstringNoAzure Cognitive Services Speech endpoint URL (e.g. https://italynorth.api.cognitive.microsoft.com).
Azure Speech KeystringNoAzure Cognitive Services Speech subscription key.
Azure Speech RegionstringNoAzure region where the Speech resource is deployed. Default: italynorth.
Default VoicestringNoDefault neural voice (e.g. it-IT-ElsaNeural, en-US-JennyNeural). Default: it-IT-ElsaNeural.
Audio FormatstringNoPCM audio format for synthesized speech. One of Riff24Khz16BitMonoPcm, Riff16Khz16BitMonoPcm, Riff8Khz16BitMonoPcm. Default: Riff16Khz16BitMonoPcm.

OpenAI TTS settings shown when TTS Provider is OpenAI.

FieldTypeRequiredDescription
OpenAI API KeystringYesOpenAI API key (sk-...).
ModelstringNoOpenAI TTS model. One of tts-1, tts-1-hd (tts-1-hd offers higher quality). Default: tts-1.
VoicestringNoVoice persona. One of alloy, echo, fable, onyx, nova, shimmer. Default: nova.
SpeednumberNoPlayback speed multiplier (0.25–4.0). Default: 1.0.

Resemble TTS settings shown when TTS Provider is Resemble.

FieldTypeRequiredDescription
Resemble API KeystringYesResemble.ai API token, sent as a Bearer token.
Voice UUIDstringYesUUID of the Resemble voice to synthesize with (from the Resemble dashboard).
Sample RatestringNoResemble output sample rate in Hz. One of 8000, 16000, 22050, 32000, 44100, 48000. Default: 16000.
PrecisionstringNoResemble audio sample precision. One of PCM_16, PCM_24, PCM_32, MULAW. Default: PCM_16.

Media Streaming

These settings matter only for the streaming voice agent. Standard IVR flows can leave them at their defaults.

FieldTypeRequiredDescription
Enable Media StreamingbooleanNoTurns on bidirectional media streaming for this Environment. Needed only by the streaming voice agent. Leave it off for standard IVR flows while the media stream is open, ACS routes the call audio through it and rejects the server-side prompt playback used by the OutputTask and InputTask, so the caller hears nothing. Default: off.
Media Token TTL (seconds)integerNoLifetime of the signed token embedded in the media-streaming URL handed to ACS (10–3600). Keep it short to limit exposure if the URL leaks. Only used when Enable Media Streaming is on. Default: 30.

Voice Agent

Optional needed only by the real-time conversational voice agent (rolling out). Leave the whole section unset for plain IVR flows. The agent listens with Azure speech recognition (reusing the Azure Speech settings above), replies through the configured LLM, and speaks with the streaming voice of the selected TTS provider.

FieldTypeRequiredDescription
STT LanguagestringNoSpeech-recognition language for the caller's voice. One of it-IT, en-US, en-GB, de-DE, fr-FR, es-ES. Falls back to the Default Language when blank.
LLM ProviderstringNoLarge-language-model backend that drives the conversation. Currently OpenAI. Default: OpenAI.
LLM ModelstringNoChat model id (e.g. gpt-4o-mini). Smaller, faster models keep per-turn latency low. Default: gpt-4o-mini.
LLM API KeystringNoAPI key for the LLM provider. Leave blank to reuse the OpenAI API Key from the Text-to-Speech settings when the LLM Provider is OpenAI.
System PromptstringNoSystem instructions that frame the agent's persona, scope, and when to end the conversation. Default: empty.
TemperaturenumberNoSampling temperature (0.0–2.0). Lower is more deterministic. Default: 0.4.
Max Tokens per TurnintegerNoCap on the length of each agent reply (16–4096 tokens). Keeps turns short and bounds cost. Default: 256.
Agent VoicestringNoVoice id for the selected TTS provider (e.g. an OpenAI voice name or a Resemble voice UUID). Blank uses that provider's configured default.
Max TurnsintegerNoHard ceiling on conversational turns before the agent ends the call (0–200). 0 = no turn limit. Default: 30.
Max Duration (seconds)integerNoHard wall-clock ceiling for the whole conversation (0–3600). 0 = no duration limit. Default: 300.
Per-Turn Timeout (seconds)integerNoHow long to wait for the caller or the model on a single turn before timing out (0–120). 0 = no per-turn timeout. Default: 20.
End IntentsstringNoComma-separated intent names the agent can call to finish the conversation (e.g. booking_complete, info_provided). Default: empty.
Handoff IntentsstringNoComma-separated intent names that end the conversation with an escalation to a human (e.g. transfer_to_agent). Default: empty.

Tasks

All four Tasks are channel-specific implementations for the AcsPhone Channel. They use the same Task types as the Standard Module the property panel in the BPMN Editor is identical to the chat versions; only the runtime behavior differs.

StartTask (Channel: AcsPhone)

Initializes the call context when a Session begins on the AcsPhone Channel.

Properties

PropertyTypeRequiredExampleDescription
(none)The StartTask has no configurable properties.

Behavior

  1. Checks that the Session is bound to a live call and that the ACS connection is configured.
  2. Records the call connection details and the call start time on the Session.
  3. Writes the Module's Default Language into the Language Session variable so downstream Tasks use it for speech synthesis.

Example

An outbound notification call begins. The Start Event records the call start time 2026-05-28T09:15:00Z and sets {Language} = en-US for the rest of the Process. The next OutputTask uses that language when it synthesizes the greeting.

OutputTask (Channel: AcsPhone)

Speaks a message to the caller using the configured TTS provider.

Properties

PropertyTypeRequiredExampleDescription
Output MessagestringYesWelcome back, {userName}. Press 1 to hear your balance.The text spoken to the caller. Supports {variable} placeholders for dynamic values.

Behavior

  1. Checks that the Session is bound to a live call, that the Output Message is non-empty, and that the ACS connection is configured.
  2. Resolves every {variable} placeholder against the current Session variables.
  3. Converts the text to audio with the active TTS provider, honoring the Voice and Language Session variables if present (otherwise falling back to the Default Language).
  4. Plays the audio to the caller over the live call.

Example

After collecting {userName} in an earlier InputTask, an OutputTask with Output Message Welcome back, {userName}. Press 1 to hear your balance. synthesizes that line in the active language and plays it to the caller. The Token then continues to the next node.

InputTask (Channel: AcsPhone)

Plays a prompt and waits for a keypad (DTMF) digit from the caller.

Properties

PropertyTypeRequiredExampleDescription
Prompt MessagestringYesPress 1 for booking, 2 to cancel.Prompt spoken to the caller before digit recognition starts. Supports {variable} placeholders.
Store in VariablestringYes{userChoice}On the AcsPhone Channel, type the variable as a {name} reference. The captured digit is written there when the caller presses a key.

Behavior

  1. Checks that the Session is bound to a live call, that the Prompt Message is non-empty, that Store in Variable is a {name} reference, and that the ACS connection is configured.
  2. Resolves {variable} placeholders in the prompt and converts it to audio with the active TTS provider, honoring the Voice and Language Session variables if set.
  3. Plays the prompt and starts keypad recognition for a single digit, with a 5-second initial silence window. The caller can press a key while the prompt is still playing.
  4. The Token waits at this node; when the digit arrives, it is written into the configured variable and the Token resumes.

Example

An IVR menu plays Prompt Message Press 1 for booking, 2 to cancel. with Store in Variable {userChoice}. The caller presses 1; {userChoice} now holds 1, and a downstream SwitchTask routes the Token to the booking branch.

EndTask (Channel: AcsPhone)

Hangs up the call when the Token reaches the End Event.

Properties

PropertyTypeRequiredExampleDescription
(none)The EndTask has no configurable properties on the AcsPhone Channel.

Behavior

  1. Checks that the Session is bound to a live call and that the ACS connection is configured.
  2. If the call is already terminated, the Task exits cleanly with no action.
  3. Otherwise it ends the call for all parties and the Session closes.

To speak a farewell to the caller, place an OutputTask with your goodbye text immediately before the End Event.

Example

After the IVR has played its goodbye message through a final OutputTask, the Token reaches the End Event. The Module ends the call, Azure tears the connection down, and the Session closes.

Common recipes

Route callers through a keypad menu

Greet the caller, collect a single digit, and branch the call with the Standard Module's SwitchTask.

  1. InputTask Prompt Message Welcome! Press 1 for bookings, 2 to cancel an appointment., Store in Variable {menuChoice}. The caller's digit lands in {menuChoice}.
  2. SwitchTask (Standard Module) Variable to evaluate {menuChoice}; Case 1: Value 1, Branch booking; Case 2: Value 2, Branch cancel; Default branch other. Label the outgoing Sequence Flows booking, cancel, and other.
  3. OutputTask, one per branch booking speaks You can book online or stay on the line., cancel speaks the cancellation instructions, and other speaks Sorry, that key is not on the menu.
  4. EndTask hangs up the call and closes the Session.

Confirm an appointment with an outbound reminder call

Format the stored appointment time with the Date Module, speak it to the customer, and capture their confirmation.

  1. Extract Date (Date Module) Operation Format text, Input date {appointmentUtc}, Pattern Custom…, Custom pattern dddd d MMMM HH:mm, Locale en-US, Time zone Europe/Rome, Output variable appointmentText. {appointmentText} becomes e.g. Monday 25 May 14:30.
  2. OutputTask Output Message Hello {customerName}, this is a reminder of your appointment on {appointmentText}.
  3. InputTask Prompt Message Press 1 to confirm, or 2 if you need to reschedule., Store in Variable {confirmChoice}.
  4. SwitchTask (Standard Module) Variable to evaluate {confirmChoice}; Case: Value 1, Branch confirmed; Default branch other.
  5. OutputTask, one per branch confirmed speaks Great, see you then!; other speaks No problem, an operator will call you back.
  6. EndTask hangs up and closes the Session.

Best practices

  1. Leave Enable Media Streaming off for IVR flows while the media stream is open, ACS rejects the server-side prompt playback the OutputTask and InputTask rely on, so callers hear nothing. Turn it on only when the Environment runs the streaming voice agent.
  2. Set Default Language to match your Default Voice speech synthesis falls back to the Default Language when no Language variable is set on the Session; aligning them avoids accent mismatches.
  3. Cap voice-agent conversations set Max Turns and Max Duration in the Voice Agent settings so a runaway conversation cannot rack up Azure minutes and LLM cost indefinitely.
  4. Validate keypad input before branching the InputTask captures a single digit; pair it with a SwitchTask on the captured variable and handle unexpected digits via the Default branch.
  5. Keep prompts short every OutputTask costs a TTS synthesis; long monologues add latency and cost. Break long messages across multiple OutputTasks. With the Resemble provider this is also a hard limit: a single synthesis accepts at most 2000 characters and the Task fails above that, so split long scripts.

Error codes

CodeNameDescription
3005TaskInvalidDataA required Task field (e.g. the message to speak) is empty. See full details
4006ModuleGenericExceptionThe call context is missing or invalid (e.g. no live call bound to the Session). See full details
4008ModuleMissingConfigurationThe ACS connection is not configured for the Environment. See full details