001/*
002 *   Copyright 2020 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.sms;
017
018
019import com.vonage.client.HttpWrapper;
020import com.vonage.client.VonageClient;
021import com.vonage.client.VonageClientException;
022import com.vonage.client.VonageResponseParseException;
023import com.vonage.client.sms.messages.Message;
024
025import java.util.ArrayList;
026import java.util.Arrays;
027import java.util.Date;
028import java.util.List;
029
030
031/**
032 * A client for talking to the Vonage Voice API. The standard way to obtain an instance of this class is to use {@link
033 * VonageClient#getSmsClient()}.
034 */
035public class SmsClient {
036    private SendMessageEndpoint message;
037    private SmsSearchEndpoint search;
038    private SearchRejectedMessagesEndpoint rejected;
039    private SmsSingleSearchEndpoint singleSearch;
040
041    /**
042     * Create a new SmsClient.
043     */
044    public SmsClient(HttpWrapper httpWrapper) {
045        this.message = new SendMessageEndpoint(httpWrapper);
046        this.search = new SmsSearchEndpoint(httpWrapper);
047        this.rejected = new SearchRejectedMessagesEndpoint(httpWrapper);
048        this.singleSearch = new SmsSingleSearchEndpoint(httpWrapper);
049    }
050
051    /**
052     * Send an SMS message.
053     * <p>
054     * This uses the supplied object to construct a request and post it to the Vonage API.<br> This method will respond
055     * with an SmsSubmissionResponse object. Depending on the nature and length of the submitted message, Vonage may
056     * automatically split the message into multiple sms messages in order to deliver to the handset. For example, a
057     * long text sms of greater than 160 chars will need to be split into multiple 'concatenated' sms messages. The
058     * Vonage service will handle this automatically for you.<br> The messages are stored as a Collection of
059     * SmsSubmissionResponseMessage objects on the SmsSubmissionResponse object. Each message can potentially have a
060     * different status result, and each message will have a different message id. Delivery notifications will be
061     * generated for each sms message within this set and will be posted to your application containing the appropriate
062     * message id.
063     *
064     * @param message The message request object that describes the type of message and the contents to be submitted.
065     *
066     * @return SmsSubmissionResponse an object containing a collection of SmsSubmissionResponseMessage objects for each
067     * actual sms that was required to submit the message.
068     *
069     * @throws VonageClientException        if there was a problem with the Vonage request or response objects.
070     * @throws VonageResponseParseException if the response from the API could not be parsed.
071     */
072    public SmsSubmissionResponse submitMessage(Message message) throws VonageResponseParseException, VonageClientException {
073        return this.message.execute(message);
074    }
075
076    /**
077     * Search for completed SMS transactions.
078     * <p>
079     * You should probably use the helper methods {@link #searchMessages(String, String...)} or {@link
080     * #searchMessages(String, String...)} instead.
081     * <p>
082     *
083     * @throws VonageClientException        if there was a problem with the Vonage request or response objects.
084     * @throws VonageResponseParseException if the response from the API could not be parsed.
085     */
086    public SearchSmsResponse searchMessages(SearchSmsRequest request) throws VonageResponseParseException, VonageClientException {
087        return this.search.execute(request);
088    }
089
090    /**
091     * Search for completed SMS transactions by ID
092     *
093     * @param id  the first ID to look up
094     * @param ids optional extra IDs to look up
095     *
096     * @return SMS data matching the provided criteria.
097     *
098     * @throws VonageClientException        if there was a problem with the Vonage request or response objects.
099     * @throws VonageResponseParseException if the response from the API could not be parsed.
100     */
101    public SearchSmsResponse searchMessages(String id, String... ids) throws VonageResponseParseException, VonageClientException {
102        List<String> idList = new ArrayList<>(ids.length + 1);
103        idList.add(id);
104        idList.addAll(Arrays.asList(ids));
105        return this.searchMessages(new SmsIdSearchRequest(idList));
106    }
107
108    /**
109     * Search for completed SMS transactions by date and recipient MSISDN.
110     *
111     * @param date the date of the SMS message to be looked up
112     * @param to   the MSISDN number of the SMS recipient
113     *
114     * @return SMS data matching the provided criteria
115     *
116     * @throws VonageClientException        if there was a problem with the Vonage request or response objects.
117     * @throws VonageResponseParseException if the response from the API could not be parsed.
118     */
119    public SearchSmsResponse searchMessages(Date date, String to) throws VonageResponseParseException, VonageClientException {
120        return this.searchMessages(new SmsDateSearchRequest(date, to));
121    }
122
123    /**
124     * Search for rejected SMS transactions using a {@link SearchRejectedMessagesRequest}.
125     * <p>
126     * You should probably use {@link #searchRejectedMessages(Date, String)} instead.
127     *
128     * @return rejection data matching the provided criteria
129     *
130     * @throws VonageClientException        if there was a problem with the Vonage request or response objects.
131     * @throws VonageResponseParseException if the response from the API could not be parsed.
132     */
133    public SearchRejectedMessagesResponse searchRejectedMessages(SearchRejectedMessagesRequest request) throws VonageResponseParseException, VonageClientException {
134        return this.rejected.execute(request);
135    }
136
137    /**
138     * Search for rejected SMS transactions by date and recipient MSISDN.
139     *
140     * @param date the date of the rejected SMS message to be looked up
141     * @param to   the MSISDN number of the SMS recipient
142     *
143     * @return rejection data matching the provided criteria
144     *
145     * @throws VonageClientException        if there was a problem with the Vonage request or response objects.
146     * @throws VonageResponseParseException if the response from the API could not be parsed.
147     */
148    public SearchRejectedMessagesResponse searchRejectedMessages(Date date, String to) throws VonageResponseParseException, VonageClientException {
149        return this.searchRejectedMessages(new SearchRejectedMessagesRequest(date, to));
150    }
151
152    /**
153     * Search for a single SMS by id.
154     *
155     * @param id The message id to search for.
156     *
157     * @return SmsSingleSearchResponse object containing the details of the SMS.
158     *
159     * @throws VonageClientException        if there was a problem with the Vonage request or response objects.
160     * @throws VonageResponseParseException if the response from the API could not be parsed.
161     */
162    public SmsSingleSearchResponse getSms(String id) throws VonageResponseParseException, VonageClientException {
163        return this.singleSearch.execute(id);
164    }
165}