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}