001/* 002 * Copyright (c) 2011-2017 Nexmo Inc 003 * 004 * Permission is hereby granted, free of charge, to any person obtaining a copy 005 * of this software and associated documentation files (the "Software"), to deal 006 * in the Software without restriction, including without limitation the rights 007 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 008 * copies of the Software, and to permit persons to whom the Software is 009 * furnished to do so, subject to the following conditions: 010 * 011 * The above copyright notice and this permission notice shall be included in 012 * all copies or substantial portions of the Software. 013 * 014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 015 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 016 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 017 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 018 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 019 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 020 * THE SOFTWARE. 021 */ 022package com.nexmo.client.voice; 023 024 025import com.nexmo.client.*; 026import com.nexmo.client.voice.ncco.Ncco; 027 028/** 029 * A client for talking to the Nexmo Voice API. The standard way to obtain an instance of this class is to use {@link 030 * NexmoClient#getVoiceClient()}. 031 */ 032public class VoiceClient extends AbstractClient { 033 protected final CallsEndpoint calls; 034 protected final StreamsEndpoint streams; 035 protected final TalkEndpoint talk; 036 protected final DtmfEndpoint dtmf; 037 protected final DownloadRecordingEndpoint downloadRecording; 038 039 /** 040 * Constructor. 041 * 042 * @param httpWrapper (required) shared HTTP wrapper object used for making REST calls. 043 */ 044 public VoiceClient(HttpWrapper httpWrapper) { 045 super(httpWrapper); 046 047 calls = new CallsEndpoint(httpWrapper); 048 streams = new StreamsEndpoint(httpWrapper); 049 talk = new TalkEndpoint(httpWrapper); 050 dtmf = new DtmfEndpoint(httpWrapper); 051 downloadRecording = new DownloadRecordingEndpoint(httpWrapper); 052 } 053 054 /** 055 * Begin a call to a phone number. 056 * 057 * @param callRequest Describing the call to be made. 058 * 059 * @return A CallEvent describing the initial state of the call, containing the {@code uuid} required to interact 060 * with the ongoing phone call. 061 * 062 * @throws NexmoClientException if there was a problem with the Nexmo request or response objects. 063 * @throws NexmoResponseParseException if the response from the API could not be parsed. 064 */ 065 public CallEvent createCall(Call callRequest) throws NexmoResponseParseException, NexmoClientException { 066 return calls.post(callRequest); 067 } 068 069 /** 070 * Obtain the first page of CallInfo objects, representing the most recent calls initiated by {@link 071 * #createCall(Call)}. 072 * 073 * @return A CallInfoPage representing the response from the Nexmo Voice API. 074 * 075 * @throws NexmoClientException if there was a problem with the Nexmo request or response objects. 076 * @throws NexmoResponseParseException if the response from the API could not be parsed. 077 */ 078 public CallInfoPage listCalls() throws NexmoResponseParseException, NexmoClientException { 079 return this.listCalls(null); 080 } 081 082 /** 083 * Obtain the first page of CallInfo objects matching the query described by {@code filter}, representing the most 084 * recent calls initiated by {@link #createCall(Call)}. 085 * 086 * @param filter (optional) A filter describing which calls to be listed. 087 * 088 * @return A CallInfoPage representing the response from the Nexmo Voice API. 089 * 090 * @throws NexmoClientException if there was a problem with the Nexmo request or response objects. 091 * @throws NexmoResponseParseException if the response from the API could not be parsed. 092 */ 093 public CallInfoPage listCalls(CallsFilter filter) throws NexmoResponseParseException, NexmoClientException { 094 return calls.get(filter); 095 } 096 097 /** 098 * Look up the status of a single call initiated by {@link #createCall(Call)}. 099 * 100 * @param uuid (required) The UUID of the call, obtained from the object returned by {@link #createCall(Call)}. This 101 * value can be obtained with {@link CallEvent#getUuid()} 102 * 103 * @return A CallInfo object, representing the response from the Nexmo Voice API. 104 * 105 * @throws NexmoClientException if there was a problem with the Nexmo request or response objects. 106 * @throws NexmoResponseParseException if the response from the API could not be parsed. 107 */ 108 public CallInfo getCallDetails(String uuid) throws NexmoResponseParseException, NexmoClientException { 109 return calls.get(uuid); 110 } 111 112 /** 113 * Send DTMF codes to an ongoing call. 114 * 115 * @param uuid (required) The UUID of the call, obtained from the object returned by {@link #createCall(Call)}. 116 * This value can be obtained with {@link CallEvent#getUuid()} 117 * @param digits (required) A string specifying the digits to be sent to the call. Valid characters are the digits 118 * {@code 1-9</tt>, <tt>#</tt>, <tt>*</tt>, with the special character <tt>p} indicating a short pause 119 * between tones. 120 * 121 * @return A CallInfo object, representing the response from the Nexmo Voice API. 122 * 123 * @throws NexmoClientException if there was a problem with the Nexmo request or response objects. 124 * @throws NexmoResponseParseException if the response from the API could not be parsed. 125 */ 126 public DtmfResponse sendDtmf(String uuid, String digits) throws NexmoResponseParseException, NexmoClientException { 127 return dtmf.put(uuid, digits); 128 } 129 130 /** 131 * Modify an ongoing call. 132 * <p> 133 * This method modifies an ongoing call, identified by "uuid". Modifications to the call can be one of: 134 * <ul> 135 * <li>Terminate the call (hangup) 136 * <li>Mute a call leg (mute) 137 * <li>Unmute a call leg (unmute) 138 * <li>Earmuff a call leg (earmuff) 139 * <li>Unearmuff a call leg (unearmuff) 140 * </ul> 141 * 142 * @param uuid The UUID of the call, obtained from the object returned by {@link #createCall(Call)}. This value 143 * can be obtained with {@link CallEvent#getUuid()} 144 * @param action One of: "hangup", "mute", "unmute", "earmuff", "unearmuff" 145 * 146 * @return A ModifyCallResponse object, representing the response from the Nexmo Voice API. 147 * 148 * @throws NexmoClientException if there was a problem with the Nexmo request or response objects. 149 * @throws NexmoResponseParseException if the response from the API could not be parsed. 150 */ 151 public ModifyCallResponse modifyCall(String uuid, ModifyCallAction action) throws NexmoResponseParseException, NexmoClientException { 152 return this.modifyCall(new CallModifier(uuid, action)); 153 } 154 155 /** 156 * Modify an ongoing call using a CallModifier object. 157 * <p> 158 * In most cases, you will want to use {@link #modifyCall(String, ModifyCallAction)} or {@link #transferCall(String, 159 * String)} instead of this method. 160 * 161 * @param modifier A CallModifier describing the modification to be made. 162 * 163 * @return A ModifyCallResponse object, representing the response from the Nexmo Voice API. 164 * 165 * @throws NexmoClientException if there was a problem with the Nexmo request or response objects. 166 * @throws NexmoResponseParseException if the response from the API could not be parsed. 167 */ 168 public ModifyCallResponse modifyCall(CallModifier modifier) throws NexmoResponseParseException, NexmoClientException { 169 return calls.put(modifier); 170 } 171 172 /** 173 * Transfer a call to a different NCCO endpoint. 174 * 175 * @param uuid The UUID of the call, obtained from the object returned by {@link #createCall(Call)}. This value 176 * can be obtained with {@link CallEvent#getUuid()} 177 * @param nccoUrl The URL of the NCCO endpoint the call should be transferred to 178 * 179 * @return A ModifyCallResponse object, representing the response from the Nexmo Voice API. 180 * 181 * @throws NexmoClientException if there was a problem with the Nexmo request or response objects. 182 * @throws NexmoResponseParseException if the response from the API could not be parsed. 183 */ 184 public ModifyCallResponse transferCall(String uuid, String nccoUrl) throws NexmoResponseParseException, NexmoClientException { 185 return this.modifyCall(CallModifier.transferCall(uuid, nccoUrl)); 186 } 187 188 /** 189 * Transfer a call to a different NCCO. 190 * 191 * @param uuid The UUID of the call, obtained from the object returned by {@link #createCall(Call)}. This value can 192 * be obtained with {@link CallEvent#getUuid()} 193 * @param ncco The new NCCO that will be used in the call. 194 * 195 * @return A ModifyCallResponse object, representing the response from the Nexmo Voice API. 196 * 197 * @throws NexmoClientException if there was a problem with the Nexmo request or response objects. 198 * @throws NexmoResponseParseException if the response from the API could not be parsed. 199 */ 200 public ModifyCallResponse transferCall(String uuid, Ncco ncco) throws NexmoResponseParseException, NexmoClientException { 201 return this.modifyCall(CallModifier.transferCall(uuid, ncco)); 202 } 203 204 /** 205 * Stream audio to an ongoing call. 206 * 207 * @param uuid The UUID of the call, obtained from the object returned by {@link #createCall(Call)}. This value 208 * can be obtained with {@link CallEvent#getUuid()} 209 * @param streamUrl A URL of an audio file in MP3 or 16-bit WAV format, to be streamed to the call. 210 * @param loop The number of times to repeat the audio. The default value is {@code 1}, or you can use {@code 211 * 0} to indicate that the audio should be repeated indefinitely. 212 * 213 * @return The data returned from the Voice API 214 * 215 * @throws NexmoClientException if there was a problem with the Nexmo request or response objects. 216 * @throws NexmoResponseParseException if the response from the API could not be parsed. 217 */ 218 public StreamResponse startStream(String uuid, String streamUrl, int loop) throws NexmoResponseParseException, NexmoClientException { 219 return streams.put(new StreamRequest(uuid, streamUrl, loop)); 220 } 221 222 /** 223 * Stream audio to an ongoing call. 224 * 225 * @param uuid The UUID of the call, obtained from the object returned by {@link #createCall(Call)}. This value 226 * can be obtained with {@link CallEvent#getUuid()} 227 * @param streamUrl A URL of an audio file in MP3 or 16-bit WAV format, to be streamed to the call. 228 * 229 * @return The data returned from the Voice API. 230 * 231 * @throws NexmoClientException if there was a problem with the Nexmo request or response objects. 232 * @throws NexmoResponseParseException if the response from the API could not be parsed. 233 */ 234 public StreamResponse startStream(String uuid, String streamUrl) throws NexmoResponseParseException, NexmoClientException { 235 return streams.put(new StreamRequest(uuid, streamUrl, 1)); 236 } 237 238 /** 239 * Stop the audio being streamed into a call. 240 * 241 * @param uuid The UUID of the call, obtained from the object returned by {@link #createCall(Call)}. This value can 242 * be obtained with {@link CallEvent#getUuid()} 243 * 244 * @return The data returned from the Voice API 245 * 246 * @throws NexmoClientException if there was a problem with the Nexmo request or response objects. 247 * @throws NexmoResponseParseException if the response from the API could not be parsed. 248 */ 249 public StreamResponse stopStream(String uuid) throws NexmoResponseParseException, NexmoClientException { 250 return streams.delete(uuid); 251 } 252 253 /** 254 * Send a synthesized speech message to an ongoing call. 255 * <p> 256 * The message will only play once, spoken with the default voice of Kimberly. 257 * 258 * @param uuid The UUID of the call, obtained from the object returned by {@link #createCall(Call)}. This value can 259 * be obtained with {@link CallEvent#getUuid()} 260 * @param text The message to be spoken to the call participants. 261 * 262 * @return The data returned from the Voice API. 263 * 264 * @throws NexmoClientException if there was a problem with the Nexmo request or response objects. 265 * @throws NexmoResponseParseException if the response from the API could not be parsed. 266 */ 267 public TalkResponse startTalk(String uuid, String text) throws NexmoResponseParseException, NexmoClientException { 268 return talk.put(new TalkRequest(uuid, text)); 269 } 270 271 /** 272 * Send a synthesized speech message to an ongoing call. 273 * 274 * @param uuid The UUID of the call, obtained from the object returned by {@link #createCall(Call)}. This value 275 * can be obtained with {@link CallEvent#getUuid()} 276 * @param text The message to be spoken to the call participants. 277 * @param voiceName The voice to be used to speak the message. 278 * 279 * @return The data returned from the Voice API. 280 * 281 * @throws NexmoClientException if there was a problem with the Nexmo request or response objects. 282 * @throws NexmoResponseParseException if the response from the API could not be parsed. 283 */ 284 public TalkResponse startTalk(String uuid, String text, VoiceName voiceName) throws NexmoResponseParseException, NexmoClientException { 285 return talk.put(new TalkRequest(uuid, text, voiceName)); 286 } 287 288 /** 289 * Send a synthesized speech message to an ongoing call. 290 * <p> 291 * The message will be spoken with the default voice of Kimberly. 292 * 293 * @param uuid The UUID of the call, obtained from the object returned by {@link #createCall(Call)}. This value can 294 * be obtained with {@link CallEvent#getUuid()} 295 * @param text The message to be spoken to the call participants. 296 * @param loop The number of times to repeat the message. The default value is {@code 1}, or you can use {@code 0} 297 * to indicate that the message should be repeated indefinitely. 298 * 299 * @return The data returned from the Voice API. 300 * 301 * @throws NexmoClientException if there was a problem with the Nexmo request or response objects. 302 * @throws NexmoResponseParseException if the response from the API could not be parsed. 303 */ 304 public TalkResponse startTalk(String uuid, String text, int loop) throws NexmoResponseParseException, NexmoClientException { 305 return talk.put(new TalkRequest(uuid, text, loop)); 306 } 307 308 /** 309 * Send a synthesized speech message to an ongoing call. 310 * 311 * @param uuid The UUID of the call, obtained from the object returned by {@link #createCall(Call)}. This value 312 * can be obtained with {@link CallEvent#getUuid()} 313 * @param text The message to be spoken to the call participants. 314 * @param voiceName The voice to be used to speak the message. 315 * @param loop The number of times to repeat the message. The default value is {@code 1}, or you can use {@code 316 * 0} to indicate that the message should be repeated indefinitely. 317 * 318 * @return The data returned from the Voice API. 319 * 320 * @throws NexmoClientException if there was a problem with the Nexmo request or response objects. 321 * @throws NexmoResponseParseException if the response from the API could not be parsed. 322 */ 323 public TalkResponse startTalk(String uuid, String text, VoiceName voiceName, int loop) throws NexmoResponseParseException, NexmoClientException { 324 return talk.put(new TalkRequest(uuid, text, voiceName, loop)); 325 } 326 327 /** 328 * Stop the message being spoken into a call. 329 * 330 * @param uuid The UUID of the call, obtained from the object returned by {@link #createCall(Call)}. This value can 331 * be obtained with {@link CallEvent#getUuid()} 332 * 333 * @return The data returned from the Voice API 334 * 335 * @throws NexmoClientException if there was a problem with the Nexmo request or response objects. 336 * @throws NexmoResponseParseException if the response from the API could not be parsed. 337 */ 338 public TalkResponse stopTalk(String uuid) throws NexmoResponseParseException, NexmoClientException { 339 return talk.delete(uuid); 340 } 341 342 /** 343 * Download a recording, given the recordingUrl provided from the webhook callback. 344 * <p> 345 * This returns a {@link Recording} object which can provide an InputStream of the byte data, or can be used to save 346 * directly to file. 347 * 348 * @param recordingUrl The recordingUrl provided by the webhook callback 349 * 350 * @return A Recording object, providing access to the recording's bytes 351 * 352 * @throws NexmoClientException if there was a problem with the Nexmo request or response objects. 353 * @throws NexmoResponseParseException if the response from the API could not be parsed. 354 */ 355 public Recording downloadRecording(String recordingUrl) throws NexmoResponseParseException, NexmoClientException { 356 return this.downloadRecording.execute(recordingUrl); 357 } 358}