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