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.sms.messages;
023
024
025import org.apache.http.client.methods.RequestBuilder;
026
027/**
028 * Represents the details common to any message that is to be submitted to the Nexmo SMS API.
029 */
030public abstract class Message {
031    public enum MessageType {
032        /**
033         * Message is a regular TEXT SMS message
034         */
035        TEXT,
036        /**
037         * Message is a binary SMS message with a custom UDH and binary payload
038         */
039        BINARY,
040        /**
041         * Message is a wap-push message to send a browsable / downloadable url to the handset
042         */
043        WAPPUSH,
044        /**
045         * Message is a unicode message, for sending messages in non-latin script to a supported handset
046         */
047        UNICODE;
048
049        public String toString() {
050            return super.toString().toLowerCase();
051        }
052    }
053
054    private final MessageType type;
055    private final String from;
056    private final String to;
057
058    private String clientReference;
059    private boolean statusReportRequired = false;
060    private MessageClass messageClass = null;
061    private Long timeToLive = null;
062    private String callbackUrl = null;
063
064    protected Message(final MessageType type,
065                      final String from,
066                      final String to) {
067        this(type, from, to, false);
068    }
069
070    /**
071     * Abstract type for more specific SMS message types.<br>
072     * This constructor exposes the full range of possible parameters and is not for general use
073     * Instead, it is accessed via super() in the constructors of various sub-classes that expose a relevant
074     * sub-set of the available parameters
075     *
076     * @param type the type of SMS message to be sent
077     * @param from the 'from' address that will be seen on the handset when this message arrives, typically either a
078     *             valid short-code / long code that can be replied to, or a short text description of the application
079     *             sending the message (Max 15 chars)
080     * @param to   the phone number of the handset you wish to send the message to
081     */
082    protected Message(final MessageType type,
083                      final String from,
084                      final String to,
085                      final boolean statusReportRequired) {
086        if (from.length() > 15) {
087            throw new IllegalArgumentException("The length of the 'from' argument must be 15 characters or fewer.");
088        }
089
090        this.type = type;
091        this.from = from;
092        this.to = to;
093        this.statusReportRequired = statusReportRequired;
094    }
095
096    /**
097     * @return int the type of message will influence the makeup of the request we post to the Nexmo server, and also the action taken by the Nexmo server in response to this message
098     */
099    public MessageType getType() {
100        return this.type;
101    }
102
103    /**
104     * @return String the 'from' address that will be seen on the handset when this message arrives,
105     * typically either a valid short-code / long code that can be replied to, or a short text description of the application sending the message (Max 11 chars)
106     */
107    public String getFrom() {
108        return this.from;
109    }
110
111    /**
112     * @return String the phone number of the handset that you wish to send the message to
113     */
114    public String getTo() {
115        return this.to;
116    }
117
118    /**
119     * @return String A user definable value that will be stored in the Nexmo sms records. It will
120     * be available in detailed reporting &amp; analytics in order to help with reconciliation of messages
121     */
122    public String getClientReference() {
123        return this.clientReference;
124    }
125
126    public void setClientReference(String clientReference) {
127        if (clientReference.length() > 40) {
128            throw new IllegalArgumentException("Client reference must be 40 characters or less.");
129        }
130        this.clientReference = clientReference;
131    }
132
133    /**
134     * @return com.nexmo.sms.verify.messages.parameters.MessageClass The message class that is to be applied to this message.
135     */
136    public MessageClass getMessageClass() {
137        return this.messageClass;
138    }
139
140    public void setMessageClass(MessageClass messageClass) {
141        this.messageClass = messageClass;
142    }
143
144    public Long getTimeToLive() {
145        return timeToLive;
146    }
147
148    public void setTimeToLive(Long timeToLive) {
149        this.timeToLive = timeToLive;
150    }
151
152    public String getCallbackUrl() {
153        return callbackUrl;
154    }
155
156    public void setCallbackUrl(String callbackUrl) {
157        this.callbackUrl = callbackUrl;
158    }
159
160    /**
161     * Get the value of the 'status-report-req' parameter.
162     */
163    public boolean getStatusReportRequired() {
164        return this.statusReportRequired;
165    }
166
167    /**
168     * Set the value of the 'status-report-req' parameter.
169     *
170     * If set to 'true', Nexmo will call 'callbackUrl' with status updates about the delivery of this message. If this
171     * value is set to 'true', then 'callbackUrl' should also be set to a URL that is configured to receive these
172     * status updates.
173     *
174     * @param statusReportRequired 'true' if status reports are desired, 'false' otherwise.
175     */
176    public void setStatusReportRequired(boolean statusReportRequired) {
177        this.statusReportRequired = statusReportRequired;
178    }
179
180    public void addParams(RequestBuilder request) {
181        request.addParameter("from", getFrom())
182                .addParameter("to", getTo())
183                .addParameter("type", getType().toString());
184        if (statusReportRequired) {
185            request.addParameter("status-report-req", "1");
186        }
187        if (clientReference != null) {
188            request.addParameter("client-ref", clientReference);
189        }
190        if (timeToLive != null) {
191            request.addParameter("ttl", timeToLive.toString());
192        }
193        if (callbackUrl != null) {
194            request.addParameter("callback", callbackUrl);
195        }
196        if (messageClass != null) {
197            request.addParameter("message-class", Integer.toString(messageClass.getMessageClass()));
198        }
199    }
200
201    /**
202     * An enum of the valid values that may be supplied to as the message-class parameter of a rest submission.
203     *
204     * @author  Paul Cook
205     */
206    public static enum MessageClass {
207
208        /**
209         * Message Class 0
210         */
211        CLASS_0(0),
212
213        /**
214         * Message Class 1
215         */
216        CLASS_1(1),
217
218        /**
219         * Message Class 2
220         */
221        CLASS_2(2),
222
223        /**
224         * Message Class 3
225         */
226        CLASS_3(3);
227
228        private final int messageClass;
229
230        private MessageClass(int messageClass) {
231            this.messageClass = messageClass;
232        }
233
234        public int getMessageClass() {
235            return this.messageClass;
236        }
237
238    }
239}