001/* 002 * Copyright 2024 Vonage 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package com.vonage.client.voice.ncco; 017 018import com.fasterxml.jackson.annotation.*; 019import com.vonage.client.JsonableBaseObject; 020import java.util.Arrays; 021import java.util.Collection; 022import java.util.Collections; 023 024/** 025 * ASR (Automatic Speech Recognition) settings for Input Actions that will be added to a NCCO object. 026 */ 027public class SpeechSettings extends JsonableBaseObject { 028 private Collection<String> uuid, context; 029 private Double endOnSilence; 030 private Integer startTimeout, maxDuration, sensitivity; 031 private Language language; 032 private Boolean saveAudio; 033 034 /** 035 * @deprecated This will be made private in a future release. Use {@link #builder()}. 036 */ 037 @Deprecated 038 public SpeechSettings() {} 039 040 private SpeechSettings(Builder builder) { 041 if (builder.uuid != null) { 042 uuid = Collections.singletonList(builder.uuid); 043 } 044 if ((endOnSilence = builder.endOnSilence) != null && (endOnSilence < 0.4 || endOnSilence > 10)) { 045 throw new IllegalArgumentException("endOnSilence must be between 0.4 and 10."); 046 } 047 if ((startTimeout = builder.startTimeout) != null && (startTimeout < 1 || startTimeout > 60)) { 048 throw new IllegalArgumentException("startTimeout must be between 1 and 60."); 049 } 050 if ((maxDuration = builder.maxDuration) != null && (maxDuration < 1 || maxDuration > 60)) { 051 throw new IllegalArgumentException("maxDuration must be between 1 and 60."); 052 } 053 if ((sensitivity = builder.sensitivity) != null && (sensitivity < 10 || sensitivity > 100)) { 054 throw new IllegalArgumentException("sensitivity must be between 10 and 100."); 055 } 056 context = builder.context; 057 language = builder.language; 058 saveAudio = builder.saveAudio; 059 } 060 061 @JsonProperty("uuid") 062 public Collection<String> getUuid() { 063 return uuid; 064 } 065 066 @JsonProperty("language") 067 public Language getLanguage() { 068 return language; 069 } 070 071 @JsonProperty("context") 072 public Collection<String> getContext() { 073 return context; 074 } 075 076 @JsonProperty("endOnSilence") 077 public Double getEndOnSilence() { 078 return endOnSilence; 079 } 080 081 @JsonProperty("startTimeout") 082 public Integer getStartTimeout() { 083 return startTimeout; 084 } 085 086 @JsonProperty("maxDuration") 087 public Integer getMaxDuration() { 088 return maxDuration; 089 } 090 091 @JsonProperty("sensitivity") 092 public Integer getSensitivity() { 093 return sensitivity; 094 } 095 096 @JsonProperty("saveAudio") 097 public Boolean getSaveAudio() { 098 return saveAudio; 099 } 100 101 102 /** 103 * @param language expected language of the user's speech. If empty, default value is en-US. 104 * @deprecated Use {@link Builder#language(Language)}. This will be removed in a future release. 105 */ 106 @Deprecated 107 public void setLanguage(Language language) { 108 this.language = language; 109 } 110 111 /** 112 * 113 * @param uuid The unique ID of the Call leg for the user to capture the speech of, wrapped in a collection. 114 * @deprecated Use {@link Builder#uuid(String)}. This will be removed in a future release. 115 */ 116 @Deprecated 117 public void setUuid(Collection<String> uuid) { 118 this.uuid = uuid; 119 } 120 121 /** 122 * List of hints to improve recognition quality if certain words are expected from the user. 123 * 124 * @param context list of hints 125 * @deprecated Use {@link Builder#context(Collection)}. This will be removed in a future release. 126 */ 127 @Deprecated 128 public void setContext(Collection<String> context) { 129 this.context = context; 130 } 131 132 /** 133 * Controls how long the system will wait after user stops speaking to decide the input is completed. 134 * Timeout range 1-10 seconds. If empty,Default value is 2 135 * 136 * @param endOnSilence wait time for voice input to complete 137 * @deprecated Use {@link Builder#endOnSilence(double)}. This will be removed in a future release. 138 */ 139 @Deprecated 140 public void setEndOnSilence(Integer endOnSilence) { 141 this.endOnSilence = Double.valueOf(endOnSilence); 142 } 143 144 /** 145 * Controls how long the system will wait for the user to start speaking. 146 * Timeout range 1-10 seconds. 147 * 148 * @param startTimeout timeout for voice input initiation 149 * @deprecated Use {@link Builder#startTimeout(int)}. This will be removed in a future release. 150 */ 151 @Deprecated 152 public void setStartTimeout(Integer startTimeout) { 153 this.startTimeout = startTimeout; 154 } 155 156 /** 157 * Controls maximum speech duration from the moment user starts speaking. Default value is 60 158 * 159 * @param maxDuration speech duration starting from user's initiation of speech 160 * @deprecated Use {@link Builder#maxDuration(int)}. This will be removed in a future release. 161 */ 162 @Deprecated 163 public void setMaxDuration(Integer maxDuration) { 164 this.maxDuration = maxDuration; 165 } 166 167 /** 168 * Entry point for constructing an instance of this class. 169 * 170 * @return A new Builder. 171 * @since 8.2.0 172 */ 173 public static Builder builder() { 174 return new Builder(); 175 } 176 177 /** 178 * Builder for customising SpeechSettings parameters. All fields are optional. 179 * 180 * @since 8.2.0 181 */ 182 public static final class Builder { 183 private String uuid; 184 private Collection<String> context; 185 private Integer startTimeout, maxDuration, sensitivity; 186 private Double endOnSilence; 187 private Language language; 188 private Boolean saveAudio; 189 190 private Builder() {} 191 192 /** 193 * The unique ID of the Call leg for the user to capture the speech of. 194 * The first joined leg of the call by default. 195 * 196 * @param uuid The call leg ID to capture as a string. 197 * @return This builder. 198 */ 199 public Builder uuid(String uuid) { 200 this.uuid = uuid; 201 return this; 202 } 203 204 /** 205 * Hints to improve recognition quality if certain words are expected from the user. 206 * 207 * @param context The collection of hint strings. 208 * @return This builder. 209 * @see #context(String...) 210 */ 211 public Builder context(Collection<String> context) { 212 this.context = context; 213 return this; 214 } 215 216 /** 217 * Hints to improve recognition quality if certain words are expected from the user. 218 * 219 * @param context The hint strings. 220 * @return This builder. 221 * @see #context(Collection) 222 */ 223 public Builder context(String... context) { 224 return context(Arrays.asList(context)); 225 } 226 227 /** 228 * Controls how long the system will wait after user stops speaking to decide the input is completed. 229 * The default value is 2.0 (seconds). The range of possible values is between 0.4 and 10.0 seconds. 230 * 231 * @param endOnSilence The input completion wait time in seconds as a double. 232 * @return This builder. 233 */ 234 public Builder endOnSilence(double endOnSilence) { 235 this.endOnSilence = endOnSilence; 236 return this; 237 } 238 239 /** 240 * Controls how long the system will wait for the user to start speaking. The range of possible values 241 * is between 1 second and 60 seconds. The default value is 10. 242 * 243 * @param startTimeout The initial speech timeout in seconds as an integer. 244 * @return This builder. 245 */ 246 public Builder startTimeout(int startTimeout) { 247 this.startTimeout = startTimeout; 248 return this; 249 } 250 251 /** 252 * Controls maximum speech duration (from the moment user starts speaking). The default value is 253 * 60 (seconds). The range of possible values is between 1 and 60 seconds. 254 * 255 * @param maxDuration The maximum speech duration in seconds as an integer. 256 * @return This builder. 257 */ 258 public Builder maxDuration(int maxDuration) { 259 this.maxDuration = maxDuration; 260 return this; 261 } 262 263 /** 264 * Audio sensitivity used to differentiate noise from speech. An integer value where 10 represents 265 * low sensitivity and 100 maximum sensitivity. Default is 90. 266 * 267 * @param sensitivity The audio sensitivity as an integer. 268 * @return This builder. 269 */ 270 public Builder sensitivity(int sensitivity) { 271 this.sensitivity = sensitivity; 272 return this; 273 } 274 275 /** 276 * Expected language of the user's speech. Default is {@link Language#ENGLISH_UNITED_STATES}. 277 * 278 * @param language The expected speech language as an enum. 279 * @return This builder. 280 */ 281 public Builder language(Language language) { 282 this.language = language; 283 return this; 284 } 285 286 /** 287 * Controls whether the speech input recording ({@code recording_url}) is sent to your webhook 288 * endpoint at {@code eventUrl}. The default value is {@code false}. 289 * 290 * @param saveAudio {@code true} to send the speech input to the event webhook. 291 * @return This builder. 292 */ 293 public Builder saveAudio(boolean saveAudio) { 294 this.saveAudio = saveAudio; 295 return this; 296 } 297 298 /** 299 * Builds the SpeechSettings object with this builder's properties. 300 * 301 * @return A new SpeechSettings instance. 302 */ 303 public SpeechSettings build() { 304 return new SpeechSettings(this); 305 } 306 } 307 308 public enum Language { 309 AFRIKAANS("af-ZA"), 310 ALBANIAN("sq-AL"), 311 AMHARIC("am-ET"), 312 ARABIC_ALGERIA("ar-DZ"), ARABIC_BAHRAIN("ar-BH"), ARABIC_EGYPT("ar-EG"), ARABIC_IRAQ("ar-IQ"), 313 ARABIC_ISRAEL("ar-IL"), ARABIC_JORDAN("ar-JO"), ARABIC_KUWAIT("ar-KW"), ARABIC_LEBANON("ar-LB"), 314 ARABIC_MOROCCO("ar-MA"), ARABIC_OMAN("ar-OM"), ARABIC_QATAR("ar-QA"), ARABIC_SAUDI_ARABIA("ar-SA"), 315 ARABIC_STATE_OF_PALESTINE("ar-PS"), ARABIC_TUNISIA("ar-TN"), ARABIC_UNITED_ARAB_EMIRATES("ar-AE"), 316 ARMENIAN("hy-AM"), 317 AZERBAIJANI("az-AZ"), 318 BASQUE("eu-EX"), 319 BENGALI_BANGLADESH("bn-BD"), 320 BENGALI_INDIA("BN-IN"), 321 BULGARIAN("bg-BG"), 322 CATALAN("ca-ES"), 323 CHINESE("zh"), 324 MANDARIN_CHINESE_SIMPLIFIED("zh-cmn-Hans-CN"), 325 CROATIAN("hr-HR"), 326 CZECH("cs-CZ"), 327 DANISH("da-DK"), 328 DUTCH("nl-NL"), 329 ENGLISH_AUSTRALIA("en-AU"), ENGLISH_CANADA("en-CA"), ENGLISH_GHANA("en-GH"), ENGLISH_INDIA("en-IN"), 330 ENGLISH_IRELAND("en-IE"), ENGLISH_KENYA("en-KE"), ENGLISH_NEW_ZEALAND("en-NZ"), ENGLISH_NIGERIA("en-NG"), 331 ENGLISH_PHILIPPINES("en-PH"), ENGLISH_SOUTH_AFRICA("en-ZA"), ENGLISH_TANZANIA("en-TZ"), 332 ENGLISH_UNITED_KINGDOM("en-GB"), ENGLISH_UNITED_STATES("en-US"), 333 FINNISH("fi-FI"), 334 FRENCH_CANADA("fr-CA"), 335 FRENCH_FRANCE("fr-FR"), 336 GALICIAN("gl-ES"), 337 GEORGIAN("ka-GE"), 338 GERMAN("de-DE"), 339 GREEK("el-GR"), 340 GUJARATI("gu-IN"), 341 HEBREW("he-IL"), 342 HINDI("hi-IN"), 343 HUNGARIAN("hu-HU"), 344 ICELANDIC("is-IS"), 345 INDONESIAN("id-ID"), 346 ITALIAN("it-IT"), 347 JAPANESE_JAPAN("ja-JP"), 348 JAVANESE("jv-ID"), 349 KANNADA("kn-IN"), 350 KHMER("km-KH"), 351 KOREAN("ko-KR"), 352 LAO("lo-LA"), 353 LATVIAN("lv-LV"), 354 LITHUANIAN("lt-LT"), 355 MALAY("ms-MY"), 356 MALAYALAM("ml-IN"), 357 MARATHI("mr-IN"), 358 NEPALI("ne-NP"), 359 NORWEGIAN_BOKMAL("nb-NO"), 360 PERSIAN("fa-IR"), 361 POLISH("pl-PL"), 362 PORTUGUESE_BRAZIL("pt-BR"), PORTUGUESE_PORTUGAL("pt-PT"), 363 ROMANIAN("ro-RO"), 364 RUSSIAN("ru-RU"), 365 SERBIAN("sr-RS"), 366 SINHALA("si-LK"), 367 SLOVAK("sk-SK"), 368 SLOVENIAN("sl-SI"), 369 SPANISH_ARGENTINA("es-AR"), SPANISH_BOLIVIA("es-BO"), SPANISH_CHILE("es-CL"), SPANISH_COLOMBIA("es-CO"), 370 SPANISH_COSTA_RICA("es-CR"), SPANISH_DOMINICAN_REPUBLIC("es-DO"), SPANISH_ECUADOR("es-EC"), SPANISH_EL_SALVADOR("es-SV"), 371 SPANISH_GUATEMALA("es-GT"), SPANISH_HONDURAS("es-HN"), SPANISH_MEXICO("es-MX"), SPANISH_NICARAGUA("es-NI"), 372 SPANISH_PANAMA("es-PA"), SPANISH_PARAGUAY("es-PY"), SPANISH_PERU("es-PE"), SPANISH_PUERTO_RICO("es-PR"), 373 SPANISH_SPAIN("es-ES"), SPANISH_UNITED_STATES("es-US"), SPANISH_URUGUAY("es-UY"), SPANISH_VENEZUELA("es-VE"), 374 SUNDANESE("su-ID"), 375 SWAHILI_KENYA("sw-KE"), SWAHILI_TANZANIA("sw-TZ"), 376 SWEDISH("sv-SE"), 377 TAMIL_INDIA("ta-IN"), TAMIL_MALAYSIA("ta-MY"), TAMIL_SINGAPORE("ta-SG"), TAMIL_SRI_LANKA("ta-LK"), 378 TELUGU("te-IN"), 379 THAI("th-TH"), 380 TURKISH("tr-TR"), 381 UKRAINIAN("uk-UA"), 382 URDU_INDIA("ur-IN"), URDU_PAKISTAN("ur-PK"), 383 VIETNAMESE("vi-VN"), 384 ZULU("zu-ZA"), 385 @JsonEnumDefaultValue 386 UNKNOWN("Unknown"); 387 388 private final String language; 389 390 @JsonCreator 391 Language(String language) { 392 this.language = language; 393 } 394 395 @JsonValue 396 public String getLanguage() { 397 return language; 398 } 399 } 400}