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