Azure 通信服务通话自动化 Java SDK

azure-communication-callautomation-java
分类编程
作者Agentic Awesome Skills 社区
许可MIT
评分4.70/5
使用11.1K

Azure Communication Call Automation (Java)

构建服务端通话自动化工作流,包括 IVR 系统、通话路由、录音以及 AI 驱动的交互。

安装

xml
<dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-communication-callautomation</artifactId>
    <version>1.6.0</version>
</dependency>

创建客户端

java
import com.azure.communication.callautomation.CallAutomationClient;
import com.azure.communication.callautomation.CallAutomationClientBuilder;
import com.azure.identity.DefaultAzureCredentialBuilder;

// 使用 DefaultAzureCredential
CallAutomationClient client = new CallAutomationClientBuilder()
.endpoint("https://<resource>.communication.azure.com")
.credential(new DefaultAzureCredentialBuilder().build())
.buildClient();

// 使用连接字符串
CallAutomationClient client = new CallAutomationClientBuilder()
.connectionString("<connection-string>")
.buildClient();

核心概念

| 类 | 用途 |
|-------|---------|
| CallAutomationClient | 发起通话、接听/拒绝呼入通话、重定向通话 |
| CallConnection | 对已建立的通话执行操作(添加参与者、终止通话) |
| CallMedia | 媒体操作(播放音频、识别 DTMF/语音) |
| CallRecording | 开始/停止/暂停录音 |
| CallAutomationEventParser | 解析来自 ACS 的 Webhook 事件 |

创建外呼通话

java
import com.azure.communication.callautomation.models.*;
import com.azure.communication.common.CommunicationUserIdentifier;
import com.azure.communication.common.PhoneNumberIdentifier;

// 拨打 PSTN 号码
PhoneNumberIdentifier target = new PhoneNumberIdentifier("+14255551234");
PhoneNumberIdentifier caller = new PhoneNumberIdentifier("+14255550100");

CreateCallOptions options = new CreateCallOptions(
new CommunicationUserIdentifier("<user-id>"), // 源
List.of(target)) // 目标
.setSourceCallerId(caller)
.setCallbackUrl("https://your-app.com/api/callbacks");

CreateCallResult result = client.createCall(options);
String callConnectionId = result.getCallConnectionProperties().getCallConnectionId();

接听呼入通话

java
// 来自 Event Grid webhook - IncomingCall 事件
String incomingCallContext = "<incoming-call-context-from-event>";

AnswerCallOptions options = new AnswerCallOptions(
incomingCallContext,
"https://your-app.com/api/callbacks");

AnswerCallResult result = client.answerCall(options);
CallConnection callConnection = result.getCallConnection();

播放音频 (文本转语音)

java
CallConnection callConnection = client.getCallConnection(callConnectionId);
CallMedia callMedia = callConnection.getCallMedia();

// 播放文本转语音 (TTS)
TextSource textSource = new TextSource()
.setText("欢迎致电 Contoso。销售请按 1,技术支持请按 2。")
.setVoiceName("en-US-JennyNeural");

PlayOptions playOptions = new PlayOptions(
List.of(textSource),
List.of(new CommunicationUserIdentifier("<target-user>")));

callMedia.play(playOptions);

// 播放音频文件
FileSource fileSource = new FileSource()
.setUrl("https://storage.blob.core.windows.net/audio/greeting.wav");

callMedia.play(new PlayOptions(Lis


t.of(fileSource), List.of(target)));
code
## 识别 DTMF 输入
java
// 识别 DTMF 拨号音
DtmfTone stopTones = DtmfTone.POUND;

CallMediaRecognizeDtmfOptions recognizeOptions = new CallMediaRecognizeDtmfOptions(
new CommunicationUserIdentifier("<target-user>"),
5) // 最大收集音数
.setInterToneTimeout(Duration.ofSeconds(5))
.setStopTones(List.of(stopTones))
.setInitialSilenceTimeout(Duration.ofSeconds(15))
.setPlayPrompt(new TextSource().setText("请输入您的账号,然后按井号。"));

callMedia.startRecognizing(recognizeOptions);

code
## 识别语音
java
// 使用 AI 进行语音识别
CallMediaRecognizeSpeechOptions speechOptions = new CallMediaRecognizeSpeechOptions(
new CommunicationUserIdentifier("<target-user>"))
.setEndSilenceTimeout(Duration.ofSeconds(2))
.setSpeechLanguage("en-US")
.setPlayPrompt(new TextSource().setText("今天我能为您提供什么帮助?"));

callMedia.startRecognizing(speechOptions);

code
## 通话录制
java
CallRecording callRecording = client.getCallRecording();

// 开始录制
StartRecordingOptions recordingOptions = new StartRecordingOptions(
new ServerCallLocator("<server-call-id>"))
.setRecordingChannel(RecordingChannel.MIXED)
.setRecordingContent(RecordingContent.AUDIO_VIDEO)
.setRecordingFormat(RecordingFormat.MP4);

RecordingStateResult recordingResult = callRecording.start(recordingOptions);
String recordingId = recordingResult.getRecordingId();

// 暂停/恢复/停止
callRecording.pause(recordingId);
callRecording.resume(recordingId);
callRecording.stop(recordingId);

// 下载录制文件(在收到 RecordingFileStatusUpdated 事件后)
callRecording.downloadTo(recordingUrl, Paths.get("recording.mp4"));

code
## 向通话添加参与者
java
CallConnection callConnection = client.getCallConnection(callConnectionId);

CommunicationUserIdentifier participant = new CommunicationUserIdentifier("<user-id>");
AddParticipantOptions addOptions = new AddParticipantOptions(participant)
.setInvitationTimeout(Duration.ofSeconds(30));

AddParticipantResult result = callConnection.addParticipant(addOptions);

code
## 转移通话
java
// 盲转 (Blind transfer)
PhoneNumberIdentifier transferTarget = new PhoneNumberIdentifier("+14255559999");
TransferCallToParticipantResult result = callConnection.transferCallToParticipant(transferTarget);
code
## 处理事件 (Webhook)
java
import com.azure.communication.callautomation.CallAutomationEventParser;
import com.azure.communication.callautomation.models.events.*;

// 在您的 Webhook 端点中
public void handleCallback(String requestBody) {
List<CallAutomationEventBase> events = CallAutomationEventParser.parseEvents(requestBody);

for (CallAutomationEventBase event : events) {
if (event instanceof CallConnected) {
CallConnected connected = (CallConnected) event;
System.out.println("通话已连接: " + connected.getCallConnectionId());
} else if (event instanceof RecognizeCompleted) {
RecognizeCompleted recognized = (RecognizeCompleted) event;
// 处理 DTMF 或语音识别结果
DtmfResult dtmfResult = (DtmfResult) recognized.getRecognizeResult();
String tones = dtmfResult.getTones().stream()
.map(DtmfTone::toString)
.collect(Collectors.joining());
System.out.println("收到 DTMF: " + tones);
} else if (event instanceof P

code
layCompleted) {
System.out.println("音频播放完成");
} else if (event instanceof CallDisconnected) {
System.out.println("通话已结束");
}
}
}

挂断通话

java
// 所有参与者均挂断
callConnection.hangUp(true);

// 仅挂断当前端点
callConnection.hangUp(false);

错误处理

java
import com.azure.core.exception.HttpResponseException;

try {
client.answerCall(options);
} catch (HttpResponseException e) {
if (e.getResponse().getStatusCode() == 404) {
System.out.println("未找到通话或通话已结束");
} else if (e.getResponse().getStatusCode() == 400) {
System.out.println("请求无效: " + e.getMessage());
}
}

环境变量

bash
AZURE_COMMUNICATION_ENDPOINT=https://<resource>.communication.azure.com
AZURE_COMMUNICATION_CONNECTION_STRING=endpoint=https://...;accesskey=...
CALLBACK_BASE_URL=https://your-app.com/api/callbacks

触发词

  • "call automation Java", "IVR Java", "interactive voice response"
  • "call recording Java", "DTMF recognition Java"
  • "text to speech call", "speech recognition call"
  • "answer incoming call", "transfer call Java"
  • "Azure Communication Services call automation"

使用场景

本技能适用于执行概览中所描述的工作流或操作。

局限性

  • 仅在任务与上述描述的范围明确匹配时使用此技能。
  • 不要将输出结果视为针对特定环境的验证、测试或专家评审的替代方案。
  • 如果缺少必要的输入、权限、安全边界或成功标准,请停止并请求澄清。