/* * TODO: The instancesByTrackingNumber will increase unbounded unless fixed * Created on Apr 27, 2004 * * To change the template for this generated file go to * Window>Preferences>Java>Code Generation>Code and Comments */ package net.reliableresponse.notification.providers; import java.io.IOException; import java.io.StringReader; import java.util.Hashtable; import java.util.Vector; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import net.reliableresponse.notification.Notification; import net.reliableresponse.notification.NotificationException; import net.reliableresponse.notification.broker.BrokerFactory; import net.reliableresponse.notification.device.AbstractDevice; import net.reliableresponse.notification.device.Device; import net.reliableresponse.notification.device.PagerDevice; import net.reliableresponse.notification.device.TAPDevice; import net.reliableresponse.notification.device.VoiceShotDevice; import net.reliableresponse.notification.usermgmt.User; import net.reliableresponse.notification.util.StringUtils; import net.reliableresponse.notification.wctp.ClientResponse; import net.reliableresponse.notification.wctp.WctpException; import net.reliableresponse.notification.wctp.WctpLibrary; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.methods.RequestEntity; import org.apache.commons.httpclient.methods.StringRequestEntity; import org.w3c.dom.DOMException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; /** * @author drig * * To change the template for this generated type comment go to * Window>Preferences>Java>Code Generation>Code and Comments */ public class VoiceShotNotificationProvider extends AbstractNotificationProvider { int status = Notification.PENDING; private String phoneNumber; private boolean hasResponded; public String getPhoneNumber() { return phoneNumber; } public void setPhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; } public VoiceShotNotificationProvider() { } public Hashtable getParameters (Notification notification, Device device) { Hashtable params = new Hashtable(); return params; } public void init(Hashtable params) throws NotificationException { // We don't need no stinkin' initialization } public Hashtable sendNotification(Notification notification, Device device) throws NotificationException { if (!(device instanceof VoiceShotDevice)) { throw new NotificationException (NotificationException.FAILED, "Supplied device is not a VoiceShot device"); } String[] responses = notification.getSender().getAvailableResponses(notification); String message =""; if ((!StringUtils.isEmpty(notification.getSender().getNotificationType()) && (!notification.getSender().getNotificationType().equalsIgnoreCase("blank")))) { message += "You have a new "+notification.getSender().getNotificationType()+" from "+notification.getSender()+". "; } if (!StringUtils.isEmpty(notification.getSubject())) { if (!notification.getSender().getNotificationType().equalsIgnoreCase("blank")) { message += "The subject is "; } message += notification.getSubject()+". "; } message +=notification.getMessages()[0].getMessage()+". "; if (notification.isPersistent()) { for (int i = 0; i < responses.length; i++) { message += "Please press " + (i+1) + " to respond with " + responses[i] + ". "; } } VoiceShotDevice voiceShotDevice = (VoiceShotDevice)device; setPhoneNumber(voiceShotDevice.getPhoneNumber()); StringBuffer xml = new StringBuffer(); xml.append ("<campaign menuid=\""); xml.append (BrokerFactory.getConfigurationBroker().getStringValue("voiceshot.campaign", "0")); xml.append ("\" action=\"0\" >\n"); xml.append ("<phonenumbers>\n"); xml.append ("<phonenumber number=\""); xml.append (voiceShotDevice.getPhoneNumber()); xml.append ("\" callid=\""); xml.append (notification.getUuid()); xml.append ("\" callerid=\""); xml.append (BrokerFactory.getConfigurationBroker().getStringValue("voiceshot.callerid", "3035551212")); xml.append ("\">\n"); xml.append ("<prompts>\n"); xml.append ("<prompt promptid=\"1\" tts=\""); xml.append (StringUtils.escapeForXML(message)); xml.append ("\" />\n"); for (int i = 0; i < responses.length; i++) { xml.append ("<prompt promptid=\""+(i+2)+"\" tts=\""+notification.getSender().getResponseMessage(responses[i])+"\" />\n"); } xml.append ("<prompt promptid=\"11\" tts=\"Thank you for using Reliable Response Notification\" />\n"); xml.append ("</prompts>\n"); xml.append ("</phonenumber>\n"); xml.append ("</phonenumbers>\n"); xml.append ("</campaign>\n"); BrokerFactory.getLoggingBroker().logDebug("Submitting XML to VoiceShot: "+xml.toString()); HttpClient httpClient = new HttpClient(); PostMethod post = new PostMethod("http://api.voiceshot.com/ivrapi.asp"); post.setParameter("Content-Type", "text/xml"); post.setRequestBody(xml.toString()); try { int result = httpClient.executeMethod(post); BrokerFactory.getLoggingBroker().logDebug("VoiceShot responded "+post.getResponseBodyAsString()); if (result != 200) { throw new NotificationException(NotificationException.FAILED, "Got a bad return code from the server: "+result); } hasResponded = false; } catch (Exception e) { BrokerFactory.getLoggingBroker().logError(e); throw new NotificationException(NotificationException.TEMPORARILY_FAILED, e.getMessage()); } Hashtable params = new Hashtable(); return params; } /** * * @param pageId * The ID of the notification previously sent * @return A english-readable status. null if the message is unknown */ public int getStatus(Notification notification) { return status; } public String[] getResponses(Notification notification) { Vector responses = new Vector(); if (hasResponded) { return new String[0]; } StringBuffer xml = new StringBuffer(); xml.append ("<campaign menuid=\"20862-2\" action=\"3\" >\n"); xml.append ("<phonenumbers>\n"); xml.append ("<phonenumber number=\""); xml.append (getPhoneNumber()); xml.append ("\" callid=\""); xml.append (notification.getUuid()); xml.append ("\" callerid=\"3035551212\">\n"); xml.append ("</phonenumber>\n"); xml.append ("</phonenumbers>\n"); xml.append ("</campaign>\n"); BrokerFactory.getLoggingBroker().logDebug("Submitting XML to VoiceShot: "+xml.toString()); HttpClient httpClient = new HttpClient(); PostMethod post = new PostMethod("http://api.voiceshot.com/ivrapi.asp"); post.setParameter("Content-Type", "text/xml"); post.setRequestBody(xml.toString()); try { int result = httpClient.executeMethod(post); String response = post.getResponseBodyAsString(); BrokerFactory.getLoggingBroker().logDebug("VoiceShot responded "+response); if (result != 200) { throw new NotificationException(NotificationException.FAILED, "Got a bad return code from the server: "+result); } // This is the XML parsing DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.parse(new InputSource(new StringReader( response))); Element campaign = document.getDocumentElement(); if (campaign == null) { BrokerFactory.getLoggingBroker().logDebug("VoiceShot notification "+notification.getUuid()+ " has no campaign"); return new String[0]; } NodeList phoneNumbers = campaign.getElementsByTagName("phonenumbers"); if (phoneNumbers == null) { BrokerFactory.getLoggingBroker().logDebug("VoiceShot notification "+notification.getUuid()+ " has no phone numbers"); return new String[0]; } for (int phoneNumberNum = 0; phoneNumberNum < phoneNumbers.getLength(); phoneNumberNum++) { Element phoneNumberElement = (Element)phoneNumbers.item(phoneNumberNum); if (phoneNumberElement == null) { BrokerFactory.getLoggingBroker().logDebug("VoiceShot notification "+notification.getUuid()+ " has no phone number"); return new String[0]; } BrokerFactory.getLoggingBroker().logDebug("VoiceShot notification "+notification.getUuid()+ " phone num element= "+phoneNumberElement.getTagName()); String statusString = phoneNumberElement.getAttribute("status"); BrokerFactory.getLoggingBroker().logDebug("VoiceShot notification "+notification.getUuid()+" status = "+statusString); NodeList prompts = phoneNumberElement.getElementsByTagName("prompts"); if ((prompts == null) || (prompts.getLength()<0)) { BrokerFactory.getLoggingBroker().logDebug("VoiceShot notification "+notification.getUuid()+ " has no prompts"); return new String[0]; } Element promptsElement = (Element)prompts.item(0); if ((prompts == null) || (prompts.getLength()<0)) { BrokerFactory.getLoggingBroker().logDebug("VoiceShot notification "+notification.getUuid()+ " has no prompts element"); return new String[0]; } if (promptsElement == null) { BrokerFactory.getLoggingBroker().logDebug("VoiceShot notification "+notification.getUuid()+ " has no prompts element"); return new String[0]; } NodeList promptList = promptsElement.getElementsByTagName("prompt"); if ((promptList == null) || (promptList.getLength()<0)) { BrokerFactory.getLoggingBroker().logDebug("VoiceShot notification "+notification.getUuid()+ " has no prompt elements"); return new String[0]; } for (int promptNum = 0; promptNum< promptList.getLength(); promptNum++) { Element promptElement = (Element)promptList.item(promptNum); String promptID = promptElement.getAttribute("promptid"); String keypress = promptElement.getAttribute("keypress"); BrokerFactory.getLoggingBroker().logDebug("VoiceShot notification "+notification.getUuid()+ " prompt id = "+promptID+",keypress="+keypress); if ( (promptID != null) && (keypress != null)) { if (promptID.equals("1")) { int responseNum = -1; try { responseNum = Integer.parseInt(keypress); hasResponded = true; // We got the number that was press. But, remember // it starts at 1, not 0, so we have to -1 responses.addElement(notification.getSender().getAvailableResponses(notification)[responseNum-1]); } catch (NumberFormatException nfExc) { } } } } } } catch (Exception e) { BrokerFactory.getLoggingBroker().logError(e); } return (String[])responses.toArray(new String[0]); } public boolean isConfirmed(Notification page) { String[] responses = getResponses(page); for (int i = 0; i < responses.length; i++) { if (responses[i].toLowerCase().equals ("confirm")) { return true; } } return false; } public boolean isPassed(Notification notification) { String[] responses = getResponses(notification); for (int i = 0; i < responses.length; i++) { if (responses[i].toLowerCase().equals ("pass")) { return true; } } return false; } /** * * @param pageId * @return Whether the cancellation was successfull */ public boolean cancelPage(Notification page) { return false; } public String getName() { return "Online Text to Speech"; } public String toString() { return getName(); } }