
com.clockworksms.ClockWorkSmsService Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of clockwork Show documentation
Show all versions of clockwork Show documentation
Clockwork SMS Java wrapper
The newest version!
package com.clockworksms;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.net.Authenticator;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.PasswordAuthentication;
import java.net.Proxy;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import com.clockworksms.xml.BalanceRequest;
import com.clockworksms.xml.BalanceResponse;
import com.clockworksms.xml.CreditRequest;
import com.clockworksms.xml.CreditResponse;
import com.clockworksms.xml.MessageRequest;
import com.clockworksms.xml.MessageResponse;
import com.clockworksms.xml.SmsResponse;
import com.clockworksms.xml.XmlRequest;
import com.clockworksms.xml.XmlResponse;
import com.clockworksms.xml.xmlSMS;
/**
* Send text messages through your ClockWork API Account.
* You will need a ClockWork API Account available from
* http://www.clockworksms.com/
*
* This library is distributed under the ISC Open Source license
* Usage:
*
* {@code
* try {
* ClockWorkSmsService service = new ClockWorkSmsService(API_KEY);
* SMS sms = new SMS("441234567890", "Hello World", "Clockwork");
* ClockworkSmsResult result = service.send(sms);
* }
* catch (ClockworkException e) {
* e.printStackTrace();
* }
* }
*
*/
public class ClockWorkSmsService {
private static final String SMS_URL = "api.clockworksms.com/xml/send";
private static final String CREDIT_URL = "api.clockworksms.com/xml/credit";
private String apiKey;
private String from;
private Boolean longMessage = null;
private Boolean truncateMessage = null;
private boolean ssl = false;
private InvalidCharacterActionEnum invalidCharacterAction = null;
private Proxy proxy;
private String proxyUsername;
private String proxyPassword;
private String version = "1.0"; // initial value. Actually read in from Manifest file
/**
* Create a new SMS object passing your ClockWork API key
* Log in to the Clockwork website to generate a new key for your account
*
* @param apiKey
* @throws Exception
*/
public ClockWorkSmsService(String apiKey) throws ClockworkException {
if(null == apiKey || apiKey.length() == 0) {
throw new ClockworkException("API key cannot be blank");
}
this.apiKey = apiKey;
// extract API version form manifest
URLClassLoader cl = (URLClassLoader) getClass().getClassLoader();
try {
URL url = cl.findResource("META-INF/MANIFEST.MF");
Manifest manifest = new Manifest(url.openStream());
Attributes attrs = manifest.getMainAttributes();
this.version = attrs.getValue("Implementation-Version");
} catch (IOException e) {
throw new ClockworkException(e);
}
}
/**
* Log in to the Clockwork website to generate a new key for your account
* @param apiKey Clockwork API key
*/
public void setApiKey(String apiKey) {
this.apiKey = apiKey;
}
/**
* @param from Number / String to send messages from, this is displayed on the recipients handset
* If left blank your account default will be used
*/
public void setFrom(String from) {
this.from = from;
}
/**
* @param longMessage Allow messages of up to 459 characters
* These take up to 3 credits to send
* If left blank your account default will be used
*/
public void setLongMessage(Boolean longMessage) {
this.longMessage = longMessage;
}
/**
* @param truncateMessage Truncate message if too long
* If left blank your account default will be used
*/
public void setTruncateMessage(Boolean truncateMessage) {
this.truncateMessage = truncateMessage;
}
/**
* @param ssl Use SSL when making requests to the API
*/
public void setSsl(boolean ssl) {
this.ssl = ssl;
}
/**
* @param invalidCharacterAction
* What to do if there's an invalid character in your message text
* Valid characters are defined in the GSM 03.38 character set
* Set this to AccountDefault to use your accounts default setting (default setting)
*/
public void setInvalidCharacterAction(
InvalidCharacterActionEnum invalidCharacterAction) {
this.invalidCharacterAction = invalidCharacterAction;
}
/**
* If a proxy servier is used, instantiate the Proxy class and set on this service
* @param proxy
*/
public void setProxy(Proxy proxy) {
this.proxy = proxy;
}
/**
* proxy server username needed if proxy requires Basic authentication
* @param proxyUsername
*/
public void setProxyUsername(String proxyUsername) {
this.proxyUsername = proxyUsername;
}
/**
* proxy server password needed if proxy requires Basic authentication
* @param proxyPassword
*/
public void setProxyPassword(String proxyPassword) {
this.proxyPassword = proxyPassword;
}
/**
* Send a single SMS message
*
* @param sms SMS to send
* @return An SMSResult object, check SMSResult.Success for send status
* @throws ClockworkException Thrown when the ClockWork API returns an error - Normally down to an invalid parameter
*/
public ClockworkSmsResult send(SMS sms) throws ClockworkException {
if(null == sms) {
throw new ClockworkException("SMS cannot be empty");
}
// convert single sms to a List
ArrayList smsList = new ArrayList(1);
smsList.add(sms);
// return first entry in response List
return send(smsList).get(0);
}
/**
* Send multiple SMS messages
*
* @param smsList List of SMS messages to send
* @return List of SMSResult objects, one per message
* @throws ClockworkException Thrown when the ClockWork API returns an error - Normally down to an invalid parameter
*/
public List send(List smsList) throws ClockworkException {
if(null == smsList || smsList.size() == 0) {
throw new ClockworkException("SMS list can't be empty");
}
int wrapperId = 0;
MessageRequest messageRequest = new MessageRequest(this.apiKey);
for(SMS sms: smsList) {
// if invalidCharacterAction is set at message level use this, else at API/Service level, else use default
InvalidCharacterActionEnum thisInvalidCharacterAction =
sms.getInvalidCharacterAction() != null ?
sms.getInvalidCharacterAction() :
this.invalidCharacterAction;
thisInvalidCharacterAction = thisInvalidCharacterAction!= null ?
thisInvalidCharacterAction :
InvalidCharacterActionEnum.AccountDefault;
xmlSMS xmlSms = new xmlSMS(
sms.getTo(),
sms.getMessage(),
!"".equals(sms.getFrom()) ? sms.getFrom() : this.from,
sms.getClientId(),
sms.getLongMessage() == null ? this.longMessage : sms.getLongMessage(),
sms.getTruncateMessage() == null ? this.truncateMessage : sms.getTruncateMessage(),
sms.getInvalidCharacterAction().getCode(),
wrapperId++
);
messageRequest.addMessage(xmlSms);
}
MessageResponse messageResponse = (MessageResponse) this.postXml(messageRequest);
if(messageResponse.hasError()) {
throw messageResponse.getException();
}
List results = new ArrayList();
for(SmsResponse response: messageResponse.getSmsResponses()) {
results.add( new ClockworkSmsResult(
response.getMessageId(),
smsList.get( response.getWrapperId() ),
response.isSuccess(),
response.getErrorNo(),
response.getErrorDescription())
);
}
return results;
}
/**
* Check the number of SMS available to send
*
* @return Number of SMS available
* @throws ClockworkException
*/
public long checkCredit() throws ClockworkException {
CreditRequest creditRequest = new CreditRequest(this.apiKey);
CreditResponse creditResponse = (CreditResponse) this.postXml(creditRequest);
if(creditResponse.hasError()) {
throw creditResponse.getException();
}
return creditResponse.getCredit();
}
/**
* Get the SMS balance
*
* @return SMS balance
* @throws ClockworkException
*/
public Balance checkBalance() throws ClockworkException {
BalanceRequest balanceRequest = new BalanceRequest(this.apiKey);
BalanceResponse balanceResponse = (BalanceResponse) this.postXml(balanceRequest);
if(balanceResponse.hasError()) {
throw balanceResponse.getException();
}
Balance balance = new Balance( balanceResponse.getBalance(), balanceResponse.getCurrencySymbol(), balanceResponse.getCurrencyCode() );
return balance;
}
/**
*
* @param xmlRequest
* @return
* @throws ClockworkException
*/
private XmlResponse postXml(XmlRequest xmlRequest) throws ClockworkException {
String urlAddress = this.getUrlAddress(xmlRequest);
try {
JAXBContext context = JAXBContext.newInstance( xmlRequest.getClassType() );
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
StringWriter writer = new StringWriter();
marshaller.marshal(xmlRequest, writer);
String httpResponse = this.makeHttpRequest(urlAddress, writer.toString());
// strip chars before XML prolog - byte order; not needed
httpResponse = httpResponse.substring( httpResponse.indexOf('<') );
context = JAXBContext.newInstance( xmlRequest.getResponseClassType() );
Unmarshaller unmarshaller = context.createUnmarshaller();
XmlResponse response = (XmlResponse) unmarshaller.unmarshal(new StringReader(httpResponse));
return response;
} catch (JAXBException e) {
throw new ClockworkException(e);
}
}
private String getUrlAddress(XmlRequest request) {
// determine if this is a secure connection
String url = this.ssl ? "https://" : "http://";
// determine service endpoint based on type of class/request passed in
if( request.getClass() == MessageRequest.class) {
url += ClockWorkSmsService.SMS_URL;
}
else {
url += ClockWorkSmsService.CREDIT_URL;
}
return url;
}
private String makeHttpRequest(String urlAddress, String payLoad) throws ClockworkException {
try {
URL url = new URL(urlAddress);
HttpURLConnection connection;
if(this.proxy != null) {
if(this.proxyUsername != null && this.proxyPassword != null) {
Authenticator authenticator = new Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
return (new PasswordAuthentication(proxyUsername,
proxyPassword.toCharArray()));
}
};
Authenticator.setDefault(authenticator);
}
connection = (HttpURLConnection)url.openConnection(proxy);
}
else {
connection = (HttpURLConnection)url.openConnection();
}
connection.setDoOutput(true);
connection.setConnectTimeout(60000);
connection.setReadTimeout(60000);
connection.setRequestMethod("POST");
connection.setUseCaches(false);
connection.setFixedLengthStreamingMode(payLoad.getBytes("UTF-8").length);
connection.setRequestProperty("content-type", "text/xml; charset=utf-8");
connection.setRequestProperty("User-Agent", "ClockWork Java Wrapper v" + this.version);
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
out.write(payLoad);
out.flush();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
String response = "";
while ((line = in.readLine()) != null) {
response += line;
}
out.close();
in.close();
int responseCode = connection.getResponseCode();
if(responseCode != 200) {
throw new ClockworkException(
"HTTP Response error posting to Clockwork server " + connection.getResponseMessage());
}
connection.disconnect();
return response;
} catch (MalformedURLException e) {
throw new ClockworkException(e);
} catch (IOException e) {
throw new ClockworkException(e);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy