Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add missing NCCO fields #510

Merged
merged 6 commits into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,21 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

# [8.2.0] - 2024-01-??
# [8.2.0] - 2024-01-29
- Added Number Insight v2 API implementation
- New webhook deserialisation POJOs for Voice: `AnswerWebhook` and `EventWebhook`
- `toString`, `equals` and `hashCode` implemented for all domain response objects
- Added `content_id` and `entity_id` parameters for Verify v2 SMS workflow
- Added Builder for Verify v2 SMS & Silent Auth workflow requests
- Updated Voice NCCOs:
- Added `mute`, `canSpeak` and `canHear` to `ConversationAction`
- Added support for call recording transcription
- Added `randomFromNumber` and `ringbackTone` to `ConnectAction`
- Improved `SpeechSettings`:
- Added `sensitivity` and `saveAudio`
- Builder for (setters and constructor are now deprecated)
- `endOnSilence` is now a Double instead of Integer
- Validation for parameter boundaries

# [8.1.0] - 2024-01-04
- Added various missing fields in Messages API:
Expand Down
51 changes: 51 additions & 0 deletions src/main/java/com/vonage/client/voice/ncco/ConnectAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.vonage.client.JsonableBaseObject;
import com.vonage.client.voice.AdvancedMachineDetection;
import com.vonage.client.voice.MachineDetection;
import java.net.URI;
import java.util.Arrays;
import java.util.Collection;

Expand All @@ -40,6 +41,8 @@ public class ConnectAction extends JsonableBaseObject implements Action {
private AdvancedMachineDetection advancedMachineDetection;
private Collection<String> eventUrl;
private EventMethod eventMethod;
private Boolean randomFromNumber;
private URI ringbackTone;

ConnectAction() {}

Expand All @@ -53,6 +56,10 @@ private ConnectAction(Builder builder) {
advancedMachineDetection = builder.advancedMachineDetection;
eventUrl = builder.eventUrl;
eventMethod = builder.eventMethod;
ringbackTone = builder.ringbackTone;
if ((randomFromNumber = builder.randomFromNumber) != null && from != null) {
throw new IllegalStateException("'randomFromNumber' and 'from' cannot be used together.");
}
}

@JsonProperty("action")
Expand Down Expand Up @@ -106,6 +113,16 @@ public EventMethod getEventMethod() {
return eventMethod;
}

@JsonProperty("randomFromNumber")
public Boolean getRandomFromNumber() {
return randomFromNumber;
}

@JsonProperty("ringbackTone")
public URI getRingbackTone() {
return ringbackTone;
}

/**
* Entry point for constructing an instance of this class.
*
Expand Down Expand Up @@ -137,6 +154,8 @@ public static class Builder {
private AdvancedMachineDetection advancedMachineDetection;
private Collection<String> eventUrl;
private EventMethod eventMethod;
private Boolean randomFromNumber;
private URI ringbackTone;

Builder(Collection<Endpoint> endpoint) {
this.endpoint = endpoint;
Expand Down Expand Up @@ -294,6 +313,38 @@ public Builder eventMethod(EventMethod eventMethod) {
return this;
}

/**
* Use a random phone number as {@code from}. The number will be selected from the list of the
* numbers assigned to the current application. The application will try to use number(s) from the
* same country as the destination (if available). If set to {@code true}, cannot be used together
* with {@linkplain #from(String)}. The default value is {@code false}.
*
* @param randomFromNumber {@code true} to use a random number instead of {@linkplain #from(String)}.
*
* @return This builder.
* @since 8.2.0
*/
public Builder randomFromNumber(boolean randomFromNumber) {
this.randomFromNumber = randomFromNumber;
return this;
}

/**
* A URL value that points to a ringback tone to be played back on repeat to the caller, so they don't
* hear silence. The tone will automatically stop playing when the call is fully connected. It's not
* recommended to use this parameter when connecting to a phone endpoint, as the carrier will supply
* their own ringback tone.
*
* @param ringbackTone The ringback tone URL as a string.
*
* @return This builder.
* @since 8.2.0
*/
public Builder ringbackTone(String ringbackTone) {
this.ringbackTone = URI.create(ringbackTone);
return this;
}

/**
* Builds the ConnectAction.
*
Expand Down
172 changes: 161 additions & 11 deletions src/main/java/com/vonage/client/voice/ncco/ConversationAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.vonage.client.JsonableBaseObject;
import java.util.Arrays;
import java.util.Collection;
import java.util.*;

/**
* An NCCO conversation action which enables the ability to host conference calls.
Expand All @@ -30,12 +30,11 @@ public class ConversationAction extends JsonableBaseObject implements Action {
private static final String ACTION = "conversation";

private String name;
private Collection<String> musicOnHoldUrl;
private Boolean startOnEnter;
private Boolean endOnExit;
private Boolean record;
private Collection<String> eventUrl;
private Boolean startOnEnter, endOnExit, record, mute;
private EventMethod eventMethod;
private Collection<String> musicOnHoldUrl, eventUrl;
private Collection<UUID> canSpeak, canHear;
private TranscriptionSettings transcription;

ConversationAction() {}

Expand All @@ -44,59 +43,95 @@ private ConversationAction(Builder builder) {
musicOnHoldUrl = builder.musicOnHoldUrl;
startOnEnter = builder.startOnEnter;
endOnExit = builder.endOnExit;
mute = builder.mute;
record = builder.record;
eventUrl = builder.eventUrl;
eventMethod = builder.eventMethod;
canSpeak = builder.canSpeak;
canHear = builder.canHear;
if ((transcription = builder.transcription) != null && (record == null || !record)) {
throw new IllegalStateException("Recording must be enabled for transcription.");
}
}

@Override
public String getAction() {
return ACTION;
}

@JsonProperty("name")
public String getName() {
return name;
}

@JsonProperty("musicOnHoldUrl")
public Collection<String> getMusicOnHoldUrl() {
return musicOnHoldUrl;
}

@JsonProperty("startOnEnter")
public Boolean getStartOnEnter() {
return startOnEnter;
}

@JsonProperty("endOnExit")
public Boolean getEndOnExit() {
return endOnExit;
}

@JsonProperty("mute")
public Boolean getMute() {
return mute;
}

@JsonProperty("record")
public Boolean getRecord() {
return record;
}

@JsonProperty("eventUrl")
public Collection<String> getEventUrl() {
return eventUrl;
}

@JsonProperty("eventMethod")
public EventMethod getEventMethod() {
return eventMethod;
}

@JsonProperty("canSpeak")
public Collection<UUID> getCanSpeak() {
return canSpeak;
}

@JsonProperty("canHear")
public Collection<UUID> getCanHear() {
return canHear;
}

@JsonProperty("transcription")
public TranscriptionSettings getTranscription() {
return transcription;
}

/**
* Entrypoint for constructing an instance of this class.
*
* @param name The name of the Conversation room.
* @return A {@link Builder}.
*
* @return A new Builder.
*/
public static Builder builder(String name) {
return new Builder(name);
}

public static class Builder {
private String name;
private Collection<String> musicOnHoldUrl;
private Boolean startOnEnter, endOnExit, record;
private Collection<String> eventUrl;
private EventMethod eventMethod;
private Boolean startOnEnter, endOnExit, record, mute;
private Collection<String> musicOnHoldUrl, eventUrl;
private Collection<UUID> canSpeak, canHear;
private TranscriptionSettings transcription;

Builder(String name) {
this.name = name;
Expand Down Expand Up @@ -209,9 +244,124 @@ public Builder eventMethod(EventMethod eventMethod) {
}

/**
* Whether to mute the participant. The audio from the participant will not be played to the
* conversation and will not be recorded. When using {@linkplain #canSpeak(Collection)}, the
* mute parameter is not supported.
*
* @param mute {@code true} to mute the participant.
*
* @return This builder.
* @since 8.2.0
*/
public Builder mute(boolean mute) {
this.mute = mute;
return this;
}

/**
* Convenience method for adding a leg ID to the {@code canSpeak} collection.
* The added leg ID will be able to hear this participant.
*
* @param uuid The participant leg ID to add as a string.
*
* @return This builder.
* @since 8.2.0
* @see #canSpeak(Collection)
*/
public Builder addCanSpeak(String uuid) {
if (canSpeak == null) {
canSpeak = new LinkedHashSet<>();
}
canSpeak.add(UUID.fromString(uuid));
return this;
}

/**
* Convenience method for adding a leg ID to the {@code canHear} collection.
* This participant will be able to hear the participant associated with the provided leg ID.
*
* @param uuid The participant leg ID to add as a string.
*
* @return This builder.
* @since 8.2.0
* @see #canHear(Collection)
*/
public Builder addCanHear(String uuid) {
if (canHear == null) {
canHear = new LinkedHashSet<>();
}
canHear.add(UUID.fromString(uuid));
return this;
}

/**
* A collection of leg UUIDs that this participant can be heard by. If not provided, the participant can
* be heard by everyone. If an empty collection is provided, the participant will not be heard by anyone.
* This will replace the current collection.
*
* @param canSpeak The leg UUIDs that can hear this participant speak.
*
* @return This builder.
* @since 8.2.0
* @see #addCanSpeak(String)
*/
public Builder canSpeak(Collection<UUID> canSpeak) {
if (canSpeak == null) {
this.canSpeak = null;
}
else {
this.canSpeak = new LinkedHashSet<>(canSpeak);
}
return this;
}

/**
* A collection of leg UUIDs that this participant can hear. If not provided, the participant can hear
* everyone. If an empty collection is provided, the participant will not hear any other participants.
* This will replace the current collection.
*
* @param canHear The leg UUIDs that this participant can hear.
*
* @return This builder.
* @since 8.2.0
* @see #addCanHear(String)
*/
public Builder canHear(Collection<UUID> canHear) {
if (canHear == null) {
this.canHear = null;
}
else {
this.canHear = new LinkedHashSet<>(canHear);
}
return this;
}

/**
* Transcription settings. If present (even if all settings are default), transcription is activated.
* The {@linkplain #record(Boolean)} parameter must be set to {@code true}.
*
* @param transcription The transcriptions settings.
*
* @return This builder.
* @since 8.2.0
*/
public Builder transcription(TranscriptionSettings transcription) {
this.transcription = transcription;
return this;
}

/**
* Builds the Conversation NCCO action.
*
* @return A new {@link ConversationAction} object from the stored builder options.
*/
public ConversationAction build() {
if (canSpeak != null) {
canSpeak = new ArrayList<>(canSpeak);
}
if (canHear != null) {
canHear = new ArrayList<>(canHear);
}
return new ConversationAction(this);
}
}
Expand Down
Loading
Loading