refactor: flatten Microsoft skills from nested to flat directory structure
Rewrote sync_microsoft_skills.py (v4) to use each SKILL.md's frontmatter 'name' field as the flat directory name under skills/, replacing the nested skills/official/microsoft/<lang>/<category>/<service>/ hierarchy. This fixes CI failures caused by the indexing, validation, and catalog scripts expecting skills/<id>/SKILL.md (depth 1). Changes: - Rewrite scripts/sync_microsoft_skills.py for flat output with collision detection - Update scripts/tests/inspect_microsoft_repo.py for flat name mapping - Update scripts/tests/test_comprehensive_coverage.py for name uniqueness checks - Delete skills/official/ nested directory - Add 129 Microsoft skills as flat directories (e.g. skills/azure-mgmt-botservice-dotnet/) - Move attribution files to docs/ (LICENSE-MICROSOFT, microsoft-skills-attribution.json) - Rebuild skills_index.json, CATALOG.md, README.md (845 total skills)
This commit is contained in:
254
skills/azure-communication-callautomation-java/SKILL.md
Normal file
254
skills/azure-communication-callautomation-java/SKILL.md
Normal file
@@ -0,0 +1,254 @@
|
||||
---
|
||||
name: azure-communication-callautomation-java
|
||||
description: Build call automation workflows with Azure Communication Services Call Automation Java SDK. Use when implementing IVR systems, call routing, call recording, DTMF recognition, text-to-speech, or AI-powered call flows.
|
||||
package: com.azure:azure-communication-callautomation
|
||||
---
|
||||
|
||||
# Azure Communication Call Automation (Java)
|
||||
|
||||
Build server-side call automation workflows including IVR systems, call routing, recording, and AI-powered interactions.
|
||||
|
||||
## Installation
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>com.azure</groupId>
|
||||
<artifactId>azure-communication-callautomation</artifactId>
|
||||
<version>1.6.0</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
## Client Creation
|
||||
|
||||
```java
|
||||
import com.azure.communication.callautomation.CallAutomationClient;
|
||||
import com.azure.communication.callautomation.CallAutomationClientBuilder;
|
||||
import com.azure.identity.DefaultAzureCredentialBuilder;
|
||||
|
||||
// With DefaultAzureCredential
|
||||
CallAutomationClient client = new CallAutomationClientBuilder()
|
||||
.endpoint("https://<resource>.communication.azure.com")
|
||||
.credential(new DefaultAzureCredentialBuilder().build())
|
||||
.buildClient();
|
||||
|
||||
// With connection string
|
||||
CallAutomationClient client = new CallAutomationClientBuilder()
|
||||
.connectionString("<connection-string>")
|
||||
.buildClient();
|
||||
```
|
||||
|
||||
## Key Concepts
|
||||
|
||||
| Class | Purpose |
|
||||
|-------|---------|
|
||||
| `CallAutomationClient` | Make calls, answer/reject incoming calls, redirect calls |
|
||||
| `CallConnection` | Actions in established calls (add participants, terminate) |
|
||||
| `CallMedia` | Media operations (play audio, recognize DTMF/speech) |
|
||||
| `CallRecording` | Start/stop/pause recording |
|
||||
| `CallAutomationEventParser` | Parse webhook events from ACS |
|
||||
|
||||
## Create Outbound Call
|
||||
|
||||
```java
|
||||
import com.azure.communication.callautomation.models.*;
|
||||
import com.azure.communication.common.CommunicationUserIdentifier;
|
||||
import com.azure.communication.common.PhoneNumberIdentifier;
|
||||
|
||||
// Call to PSTN number
|
||||
PhoneNumberIdentifier target = new PhoneNumberIdentifier("+14255551234");
|
||||
PhoneNumberIdentifier caller = new PhoneNumberIdentifier("+14255550100");
|
||||
|
||||
CreateCallOptions options = new CreateCallOptions(
|
||||
new CommunicationUserIdentifier("<user-id>"), // Source
|
||||
List.of(target)) // Targets
|
||||
.setSourceCallerId(caller)
|
||||
.setCallbackUrl("https://your-app.com/api/callbacks");
|
||||
|
||||
CreateCallResult result = client.createCall(options);
|
||||
String callConnectionId = result.getCallConnectionProperties().getCallConnectionId();
|
||||
```
|
||||
|
||||
## Answer Incoming Call
|
||||
|
||||
```java
|
||||
// From Event Grid webhook - IncomingCall event
|
||||
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();
|
||||
```
|
||||
|
||||
## Play Audio (Text-to-Speech)
|
||||
|
||||
```java
|
||||
CallConnection callConnection = client.getCallConnection(callConnectionId);
|
||||
CallMedia callMedia = callConnection.getCallMedia();
|
||||
|
||||
// Play text-to-speech
|
||||
TextSource textSource = new TextSource()
|
||||
.setText("Welcome to Contoso. Press 1 for sales, 2 for support.")
|
||||
.setVoiceName("en-US-JennyNeural");
|
||||
|
||||
PlayOptions playOptions = new PlayOptions(
|
||||
List.of(textSource),
|
||||
List.of(new CommunicationUserIdentifier("<target-user>")));
|
||||
|
||||
callMedia.play(playOptions);
|
||||
|
||||
// Play audio file
|
||||
FileSource fileSource = new FileSource()
|
||||
.setUrl("https://storage.blob.core.windows.net/audio/greeting.wav");
|
||||
|
||||
callMedia.play(new PlayOptions(List.of(fileSource), List.of(target)));
|
||||
```
|
||||
|
||||
## Recognize DTMF Input
|
||||
|
||||
```java
|
||||
// Recognize DTMF tones
|
||||
DtmfTone stopTones = DtmfTone.POUND;
|
||||
|
||||
CallMediaRecognizeDtmfOptions recognizeOptions = new CallMediaRecognizeDtmfOptions(
|
||||
new CommunicationUserIdentifier("<target-user>"),
|
||||
5) // Max tones to collect
|
||||
.setInterToneTimeout(Duration.ofSeconds(5))
|
||||
.setStopTones(List.of(stopTones))
|
||||
.setInitialSilenceTimeout(Duration.ofSeconds(15))
|
||||
.setPlayPrompt(new TextSource().setText("Enter your account number followed by pound."));
|
||||
|
||||
callMedia.startRecognizing(recognizeOptions);
|
||||
```
|
||||
|
||||
## Recognize Speech
|
||||
|
||||
```java
|
||||
// Speech recognition with AI
|
||||
CallMediaRecognizeSpeechOptions speechOptions = new CallMediaRecognizeSpeechOptions(
|
||||
new CommunicationUserIdentifier("<target-user>"))
|
||||
.setEndSilenceTimeout(Duration.ofSeconds(2))
|
||||
.setSpeechLanguage("en-US")
|
||||
.setPlayPrompt(new TextSource().setText("How can I help you today?"));
|
||||
|
||||
callMedia.startRecognizing(speechOptions);
|
||||
```
|
||||
|
||||
## Call Recording
|
||||
|
||||
```java
|
||||
CallRecording callRecording = client.getCallRecording();
|
||||
|
||||
// Start recording
|
||||
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();
|
||||
|
||||
// Pause/resume/stop
|
||||
callRecording.pause(recordingId);
|
||||
callRecording.resume(recordingId);
|
||||
callRecording.stop(recordingId);
|
||||
|
||||
// Download recording (after RecordingFileStatusUpdated event)
|
||||
callRecording.downloadTo(recordingUrl, Paths.get("recording.mp4"));
|
||||
```
|
||||
|
||||
## Add Participant to Call
|
||||
|
||||
```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);
|
||||
```
|
||||
|
||||
## Transfer Call
|
||||
|
||||
```java
|
||||
// Blind transfer
|
||||
PhoneNumberIdentifier transferTarget = new PhoneNumberIdentifier("+14255559999");
|
||||
TransferCallToParticipantResult result = callConnection.transferCallToParticipant(transferTarget);
|
||||
```
|
||||
|
||||
## Handle Events (Webhook)
|
||||
|
||||
```java
|
||||
import com.azure.communication.callautomation.CallAutomationEventParser;
|
||||
import com.azure.communication.callautomation.models.events.*;
|
||||
|
||||
// In your webhook endpoint
|
||||
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("Call connected: " + connected.getCallConnectionId());
|
||||
} else if (event instanceof RecognizeCompleted) {
|
||||
RecognizeCompleted recognized = (RecognizeCompleted) event;
|
||||
// Handle DTMF or speech recognition result
|
||||
DtmfResult dtmfResult = (DtmfResult) recognized.getRecognizeResult();
|
||||
String tones = dtmfResult.getTones().stream()
|
||||
.map(DtmfTone::toString)
|
||||
.collect(Collectors.joining());
|
||||
System.out.println("DTMF received: " + tones);
|
||||
} else if (event instanceof PlayCompleted) {
|
||||
System.out.println("Audio playback completed");
|
||||
} else if (event instanceof CallDisconnected) {
|
||||
System.out.println("Call ended");
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Hang Up Call
|
||||
|
||||
```java
|
||||
// Hang up for all participants
|
||||
callConnection.hangUp(true);
|
||||
|
||||
// Hang up only this leg
|
||||
callConnection.hangUp(false);
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
```java
|
||||
import com.azure.core.exception.HttpResponseException;
|
||||
|
||||
try {
|
||||
client.answerCall(options);
|
||||
} catch (HttpResponseException e) {
|
||||
if (e.getResponse().getStatusCode() == 404) {
|
||||
System.out.println("Call not found or already ended");
|
||||
} else if (e.getResponse().getStatusCode() == 400) {
|
||||
System.out.println("Invalid request: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
## Trigger Phrases
|
||||
|
||||
- "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"
|
||||
Reference in New Issue
Block a user