All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.clockworksms.ClockWorkSmsService Maven / Gradle / Ivy

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